1
+ /* *
2
+ * Copyright (C) Robotec AI - All Rights Reserved
3
+ *
4
+ * This source code is protected under international copyright law. All rights
5
+ * reserved and protected by the copyright holders.
6
+ * This file is confidential and only available to authorized individuals with the
7
+ * permission of the copyright holders. If you encounter this file and do not have
8
+ * permission, please contact the copyright holders and delete this file.
9
+ */
1
10
2
11
#include " ROS2PoseControl.h"
3
- #include " AzCore/Debug/Trace.h"
4
12
5
13
#include < AzCore/Component/ComponentApplicationBus.h>
6
14
#include < AzCore/Component/TransformBus.h>
17
25
#include < ROS2/Georeference/GeoreferenceBus.h>
18
26
#include < ROS2/Utilities/ROS2Conversions.h>
19
27
#include < ROS2/Utilities/ROS2Names.h>
20
- #include < ROS2PoseControl/ROS2PoseControlConfiguration.h>
21
28
#include < RigidBodyComponent.h>
22
29
#include < imgui/imgui.h>
23
30
#include < tf2_ros/transform_listener.h>
@@ -38,16 +45,43 @@ namespace ROS2PoseControl
38
45
}
39
46
40
47
void ROS2PoseControl::Activate ()
48
+ {
49
+ InitializeROSConnection ();
50
+ ImGui::ImGuiUpdateListenerBus::Handler::BusConnect ();
51
+ ROS2PoseControlRequestsBus::Handler::BusConnect (GetEntityId ());
52
+
53
+ AZ::TickBus::QueueFunction (
54
+ [this ]()
55
+ {
56
+ AZStd::vector<AZ::EntityId> entityIds;
57
+ AZ::TransformBus::EventResult (entityIds, GetEntityId (), &AZ::TransformBus::Events::GetAllDescendants);
58
+ for (const auto & entityId : entityIds)
59
+ {
60
+ AZ::Transform localTM = AZ::Transform::CreateIdentity ();
61
+ AZ::TransformBus::EventResult (localTM, entityId, &AZ::TransformBus::Events::GetLocalTM);
62
+ m_localTransforms[entityId] = localTM;
63
+ }
64
+ });
65
+ }
66
+
67
+ void ROS2PoseControl::Deactivate ()
68
+ {
69
+ ROS2PoseControlRequestsBus::Handler::BusDisconnect ();
70
+ ImGui::ImGuiUpdateListenerBus::Handler::BusDisconnect ();
71
+ DeinitializeROSConnection ();
72
+ }
73
+
74
+ void ROS2PoseControl::InitializeROSConnection ()
41
75
{
42
76
auto ros2Node = ROS2::ROS2Interface::Get ()->GetNode ();
43
77
m_tf_buffer = std::make_unique<tf2_ros::Buffer>(ros2Node->get_clock ());
44
78
m_tf_listener = std::make_shared<tf2_ros::TransformListener>(*m_tf_buffer);
45
79
46
- if (m_configuration.m_tracking_mode == ROS2PoseControlConfiguration:: TrackingMode::TF2)
80
+ if (m_configuration.m_tracking_mode == TrackingMode::TF2)
47
81
{
48
82
AZ::TickBus::Handler::BusConnect ();
49
83
}
50
- else if (m_configuration.m_tracking_mode == ROS2PoseControlConfiguration:: TrackingMode::PoseMessages)
84
+ else if (m_configuration.m_tracking_mode == TrackingMode::PoseMessages)
51
85
{
52
86
// Get odom frame Id
53
87
const auto * ros2_frame_component = m_entity->FindComponent <ROS2::ROS2FrameComponent>();
@@ -72,16 +106,14 @@ namespace ROS2PoseControl
72
106
73
107
);
74
108
}
75
- ImGui::ImGuiUpdateListenerBus::Handler::BusConnect ();
76
109
}
77
110
78
- void ROS2PoseControl::Deactivate ()
111
+ void ROS2PoseControl::DeinitializeROSConnection ()
79
112
{
80
113
m_poseSubscription.reset ();
81
114
m_tf_buffer.reset ();
82
115
m_tf_listener.reset ();
83
116
AZ::TickBus::Handler::BusDisconnect ();
84
- ImGui::ImGuiUpdateListenerBus::Handler::BusDisconnect ();
85
117
}
86
118
87
119
void ROS2PoseControl::EnablePhysics ()
@@ -94,6 +126,63 @@ namespace ROS2PoseControl
94
126
SetPhysicsEnabled (false );
95
127
}
96
128
129
+ void ROS2PoseControl::SetTrackingMode (TrackingMode trackingMode)
130
+ {
131
+ m_configuration.m_tracking_mode = trackingMode;
132
+ m_configurationChanged = true ;
133
+ }
134
+
135
+ void ROS2PoseControl::SetTargetFrame (const AZStd::string& targetFrame)
136
+ {
137
+ m_configuration.m_targetFrame = targetFrame;
138
+ m_configurationChanged = true ;
139
+ }
140
+
141
+ void ROS2PoseControl::SetReferenceFrame (const AZStd::string& referenceFrame)
142
+ {
143
+ m_configuration.m_referenceFrame = referenceFrame;
144
+ m_configurationChanged = true ;
145
+ }
146
+
147
+ void ROS2PoseControl::SetEnablePhysics (bool enable)
148
+ {
149
+ if (m_configuration.m_enablePhysics != enable)
150
+ {
151
+ SetPhysicsEnabled (enable);
152
+ m_configuration.m_enablePhysics = enable;
153
+ }
154
+ }
155
+
156
+ void ROS2PoseControl::SetRigidBodiesToKinematic (bool enable)
157
+ {
158
+ if (m_configuration.m_isKinematic != enable)
159
+ {
160
+ AZStd::vector<AZ::EntityId> entityIds;
161
+ AZ::TransformBus::EventResult (entityIds, GetEntityId (), &AZ::TransformBus::Events::GetAllDescendants);
162
+ entityIds.push_back (GetEntityId ());
163
+ for (const AZ::EntityId& entityId : entityIds)
164
+ {
165
+ AZ::Entity* entity;
166
+ AZ::ComponentApplicationBus::BroadcastResult (entity, &AZ::ComponentApplicationRequests::FindEntity, entityId);
167
+ if (auto * rigidBodyComponent = entity->FindComponent <PhysX::RigidBodyComponent>())
168
+ {
169
+ rigidBodyComponent->SetKinematic (enable);
170
+ }
171
+ }
172
+ m_configuration.m_isKinematic = enable;
173
+ }
174
+ }
175
+
176
+ void ROS2PoseControl::ApplyConfiguration ()
177
+ {
178
+ if (m_configurationChanged)
179
+ {
180
+ DeinitializeROSConnection ();
181
+ InitializeROSConnection ();
182
+ m_configurationChanged = false ;
183
+ }
184
+ }
185
+
97
186
void ROS2PoseControl::SetPhysicsEnabled (bool enabled)
98
187
{
99
188
AZStd::vector<AZ::EntityId> entityIds;
@@ -138,16 +227,21 @@ namespace ROS2PoseControl
138
227
if (m_tf_buffer->canTransform (targetFrame.c_str (), sourceFrame.c_str (), tf2::TimePointZero, &errorString))
139
228
{
140
229
transformStamped = m_tf_buffer->lookupTransform (targetFrame.c_str (), sourceFrame.c_str (), tf2::TimePointZero);
230
+ m_tfWarningLogShown = false ;
141
231
}
142
232
else
143
233
{
144
- AZ_Warning (
145
- " ROS2PositionControl" ,
146
- false ,
147
- " Could not transform %s to %s, error: %s" ,
148
- m_configuration.m_targetFrame .c_str (),
149
- m_configuration.m_referenceFrame .c_str (),
150
- errorString.c_str ());
234
+ if (!m_tfWarningLogShown)
235
+ {
236
+ AZ_Warning (
237
+ " ROS2PoseControl" ,
238
+ false ,
239
+ " Could not transform %s to %s, error: %s" ,
240
+ m_configuration.m_targetFrame .c_str (),
241
+ m_configuration.m_referenceFrame .c_str (),
242
+ errorString.c_str ());
243
+ m_tfWarningLogShown = true ;
244
+ }
151
245
return AZ::Failure ();
152
246
}
153
247
@@ -185,7 +279,7 @@ namespace ROS2PoseControl
185
279
186
280
void ROS2PoseControl::OnPoseMessageReceived (const geometry_msgs::msg::PoseStamped::SharedPtr msg)
187
281
{
188
- if (m_configuration.m_tracking_mode != ROS2PoseControlConfiguration:: TrackingMode::PoseMessages)
282
+ if (m_configuration.m_tracking_mode != TrackingMode::PoseMessages)
189
283
{
190
284
return ;
191
285
}
@@ -235,7 +329,7 @@ namespace ROS2PoseControl
235
329
236
330
void ROS2PoseControl::OnTick (float deltaTime, AZ::ScriptTimePoint time)
237
331
{
238
- if (m_configuration.m_tracking_mode == ROS2PoseControlConfiguration:: TrackingMode::TF2)
332
+ if (m_configuration.m_tracking_mode == TrackingMode::TF2)
239
333
{
240
334
const AZ::Outcome<AZ::Transform, void > transform_outcome = GetCurrentTransformViaTF2 ();
241
335
if (!transform_outcome.IsSuccess ())
@@ -250,7 +344,7 @@ namespace ROS2PoseControl
250
344
{
251
345
if (auto * serialize = azrtti_cast<AZ::SerializeContext*>(context))
252
346
{
253
- serialize->Class <ROS2PoseControl, AZ::Component>()->Version (1 )->Field (" m_configuration" , &ROS2PoseControl::m_configuration);
347
+ serialize->Class <ROS2PoseControl, AZ::Component>()->Version (2 )->Field (" m_configuration" , &ROS2PoseControl::m_configuration);
254
348
255
349
if (AZ::EditContext* ec = serialize->GetEditContext ())
256
350
{
@@ -274,9 +368,7 @@ namespace ROS2PoseControl
274
368
ImGui::Begin (ss.str ().c_str ());
275
369
ImGui::Checkbox (" Lock Z Axis" , &m_configuration.m_lockZAxis );
276
370
ImGui::Checkbox (" Clamp to Ground" , &m_configuration.m_clampToGround );
277
- ImGui::Text (
278
- " Tracking Mode: %s" ,
279
- m_configuration.m_tracking_mode == ROS2PoseControlConfiguration::TrackingMode::TF2 ? " TF2" : " Pose Messages" );
371
+ ImGui::Text (" Tracking Mode: %s" , m_configuration.m_tracking_mode == TrackingMode::TF2 ? " TF2" : " Pose Messages" );
280
372
281
373
ImGui::Text (
282
374
" Position %f %f %f" ,
@@ -361,8 +453,25 @@ namespace ROS2PoseControl
361
453
return ;
362
454
}
363
455
364
- // Disable physics to allow transform movement.
365
- DisablePhysics ();
456
+ if (m_configuration.m_enablePhysics )
457
+ {
458
+ // Disable physics to allow transform movement.
459
+ DisablePhysics ();
460
+ }
461
+
462
+ // If prefab has physics disabled or all of its rigid bodies are set to 'Kinematic'
463
+ // then we want to restore the initial positions of all entities. These positions
464
+ // may have changed before the physics or kinematics were enabled/disabled via
465
+ // the EBus request
466
+ if (!m_initialPositionRestored && (!m_configuration.m_enablePhysics || m_configuration.m_isKinematic ))
467
+ {
468
+ for (const auto & [entityId, localTM] : m_localTransforms)
469
+ {
470
+ AZ::TransformBus::Event (entityId, &AZ::TransformBus::Events::SetLocalTM, localTM);
471
+ }
472
+
473
+ m_initialPositionRestored = true ;
474
+ }
366
475
367
476
AZ::Transform modifiedTransform = m_configuration.m_lockZAxis ? RemoveTilt (transform) : transform;
368
477
@@ -390,8 +499,11 @@ namespace ROS2PoseControl
390
499
391
500
AZ::TransformBus::Event (GetEntityId (), &AZ::TransformBus::Events::SetWorldTM, modifiedTransform);
392
501
393
- // Re-enable physics after the transform is applied.
394
- EnablePhysics ();
502
+ if (m_configuration.m_enablePhysics )
503
+ {
504
+ // Re-enable physics after the transform is applied.
505
+ EnablePhysics ();
506
+ }
395
507
}
396
508
397
509
AZStd::optional<AZ::Vector3> ROS2PoseControl::QueryGround (
0 commit comments