Skip to content

Commit 74303eb

Browse files
Added ROS2PoseControlRequestsBus (#112)
* Extended ROS2PoseControl with its own EBus *additionally some changes in the structure are added, to allow to use ROS2PoseControl class outside of the gem Signed-off-by: Patryk Antosz <[email protected]> * Added quick fix Signed-off-by: Patryk Antosz <[email protected]> * Code refactored, added description in comments Signed-off-by: Patryk Antosz <[email protected]> * Added information about licence to all ROS2PoseControl code files *additionaly gem.json has been updated Signed-off-by: Patryk Antosz <[email protected]> * Applied review suggestions Signed-off-by: Patryk Antosz <[email protected]> * Applied review suggestions Signed-off-by: Patryk Antosz <[email protected]> * Modified cmake files Signed-off-by: Patryk Antosz <[email protected]> * Fix typos, remove unnecessary const Signed-off-by: Paweł Liberadzki <[email protected]> --------- Signed-off-by: Patryk Antosz <[email protected]> Signed-off-by: Paweł Liberadzki <[email protected]> Co-authored-by: Paweł Liberadzki <[email protected]>
1 parent e312fa6 commit 74303eb

18 files changed

+346
-44
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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+
*/
10+
11+
#pragma once
12+
13+
#include "ROS2PoseControlTypeIds.h"
14+
15+
#include <AzCore/Component/ComponentBus.h>
16+
#include <AzCore/EBus/EBus.h>
17+
18+
namespace ROS2PoseControl
19+
{
20+
enum class TrackingMode
21+
{
22+
PoseMessages,
23+
TF2
24+
};
25+
26+
//! Interface for the ROS2PoseControl
27+
//! Used for configuring the ROS2PoseControl at runtime
28+
class ROS2PoseControlRequests : public AZ::ComponentBus
29+
{
30+
public:
31+
AZ_RTTI(ROS2PoseControlRequests, ROS2PoseControlRequestsTypeId)
32+
33+
//! Set the tracking mode
34+
//! @param trackingMode - new tracking mode, to check available tracking modes @see ROS2PoseControlConfiguration
35+
virtual void SetTrackingMode(TrackingMode trackingMode) = 0;
36+
37+
//! Set the target frame that is used in the TF2 tracking mode
38+
//! @param targetFrame - name of the frame that will be used as a target frame in a lookupTransform method
39+
virtual void SetTargetFrame(const AZStd::string& targetFrame) = 0;
40+
41+
//! Set the reference frame that is used in the TF2 tracking mode
42+
//! @param referenceFrame - name of the frame that will be used as a reference (source) frame in a lookupTransform method
43+
virtual void SetReferenceFrame(const AZStd::string& referenceFrame) = 0;
44+
45+
//! Enable or disable physics for all prefab's rigid bodies
46+
//! @param enable - enable/disable flag
47+
virtual void SetEnablePhysics(bool enable) = 0;
48+
49+
//! Change the prefab's rigid bodies to either Kinematic (enable==true) or Simulated (enable==false)
50+
//! @param enable - enable/disable flag
51+
virtual void SetRigidBodiesToKinematic(bool enable) = 0;
52+
53+
//! Apply configuration of the ROS2PoseControl in its current state. In general this function reinitialize the ROS2 intestines of
54+
//! the ROS2PoseControl
55+
virtual void ApplyConfiguration() = 0;
56+
};
57+
58+
using ROS2PoseControlRequestsBus = AZ::EBus<ROS2PoseControlRequests>;
59+
} // namespace ROS2PoseControl

Gems/ROS2PoseControl/Code/Include/ROS2PoseControl/ROS2PoseControlTypeIds.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
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+
*/
110

211
#pragma once
312

Gems/ROS2PoseControl/Code/Source/Clients/ROS2PoseControl.cpp

Lines changed: 136 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
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+
*/
110

211
#include "ROS2PoseControl.h"
3-
#include "AzCore/Debug/Trace.h"
412

513
#include <AzCore/Component/ComponentApplicationBus.h>
614
#include <AzCore/Component/TransformBus.h>
@@ -17,7 +25,6 @@
1725
#include <ROS2/Georeference/GeoreferenceBus.h>
1826
#include <ROS2/Utilities/ROS2Conversions.h>
1927
#include <ROS2/Utilities/ROS2Names.h>
20-
#include <ROS2PoseControl/ROS2PoseControlConfiguration.h>
2128
#include <RigidBodyComponent.h>
2229
#include <imgui/imgui.h>
2330
#include <tf2_ros/transform_listener.h>
@@ -38,16 +45,43 @@ namespace ROS2PoseControl
3845
}
3946

4047
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()
4175
{
4276
auto ros2Node = ROS2::ROS2Interface::Get()->GetNode();
4377
m_tf_buffer = std::make_unique<tf2_ros::Buffer>(ros2Node->get_clock());
4478
m_tf_listener = std::make_shared<tf2_ros::TransformListener>(*m_tf_buffer);
4579

46-
if (m_configuration.m_tracking_mode == ROS2PoseControlConfiguration::TrackingMode::TF2)
80+
if (m_configuration.m_tracking_mode == TrackingMode::TF2)
4781
{
4882
AZ::TickBus::Handler::BusConnect();
4983
}
50-
else if (m_configuration.m_tracking_mode == ROS2PoseControlConfiguration::TrackingMode::PoseMessages)
84+
else if (m_configuration.m_tracking_mode == TrackingMode::PoseMessages)
5185
{
5286
// Get odom frame Id
5387
const auto* ros2_frame_component = m_entity->FindComponent<ROS2::ROS2FrameComponent>();
@@ -72,16 +106,14 @@ namespace ROS2PoseControl
72106

73107
);
74108
}
75-
ImGui::ImGuiUpdateListenerBus::Handler::BusConnect();
76109
}
77110

78-
void ROS2PoseControl::Deactivate()
111+
void ROS2PoseControl::DeinitializeROSConnection()
79112
{
80113
m_poseSubscription.reset();
81114
m_tf_buffer.reset();
82115
m_tf_listener.reset();
83116
AZ::TickBus::Handler::BusDisconnect();
84-
ImGui::ImGuiUpdateListenerBus::Handler::BusDisconnect();
85117
}
86118

87119
void ROS2PoseControl::EnablePhysics()
@@ -94,6 +126,63 @@ namespace ROS2PoseControl
94126
SetPhysicsEnabled(false);
95127
}
96128

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+
97186
void ROS2PoseControl::SetPhysicsEnabled(bool enabled)
98187
{
99188
AZStd::vector<AZ::EntityId> entityIds;
@@ -138,16 +227,21 @@ namespace ROS2PoseControl
138227
if (m_tf_buffer->canTransform(targetFrame.c_str(), sourceFrame.c_str(), tf2::TimePointZero, &errorString))
139228
{
140229
transformStamped = m_tf_buffer->lookupTransform(targetFrame.c_str(), sourceFrame.c_str(), tf2::TimePointZero);
230+
m_tfWarningLogShown = false;
141231
}
142232
else
143233
{
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+
}
151245
return AZ::Failure();
152246
}
153247

@@ -185,7 +279,7 @@ namespace ROS2PoseControl
185279

186280
void ROS2PoseControl::OnPoseMessageReceived(const geometry_msgs::msg::PoseStamped::SharedPtr msg)
187281
{
188-
if (m_configuration.m_tracking_mode != ROS2PoseControlConfiguration::TrackingMode::PoseMessages)
282+
if (m_configuration.m_tracking_mode != TrackingMode::PoseMessages)
189283
{
190284
return;
191285
}
@@ -235,7 +329,7 @@ namespace ROS2PoseControl
235329

236330
void ROS2PoseControl::OnTick(float deltaTime, AZ::ScriptTimePoint time)
237331
{
238-
if (m_configuration.m_tracking_mode == ROS2PoseControlConfiguration::TrackingMode::TF2)
332+
if (m_configuration.m_tracking_mode == TrackingMode::TF2)
239333
{
240334
const AZ::Outcome<AZ::Transform, void> transform_outcome = GetCurrentTransformViaTF2();
241335
if (!transform_outcome.IsSuccess())
@@ -250,7 +344,7 @@ namespace ROS2PoseControl
250344
{
251345
if (auto* serialize = azrtti_cast<AZ::SerializeContext*>(context))
252346
{
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);
254348

255349
if (AZ::EditContext* ec = serialize->GetEditContext())
256350
{
@@ -274,9 +368,7 @@ namespace ROS2PoseControl
274368
ImGui::Begin(ss.str().c_str());
275369
ImGui::Checkbox("Lock Z Axis", &m_configuration.m_lockZAxis);
276370
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");
280372

281373
ImGui::Text(
282374
"Position %f %f %f",
@@ -361,8 +453,25 @@ namespace ROS2PoseControl
361453
return;
362454
}
363455

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+
}
366475

367476
AZ::Transform modifiedTransform = m_configuration.m_lockZAxis ? RemoveTilt(transform) : transform;
368477

@@ -390,8 +499,11 @@ namespace ROS2PoseControl
390499

391500
AZ::TransformBus::Event(GetEntityId(), &AZ::TransformBus::Events::SetWorldTM, modifiedTransform);
392501

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+
}
395507
}
396508

397509
AZStd::optional<AZ::Vector3> ROS2PoseControl::QueryGround(

0 commit comments

Comments
 (0)