Skip to content

Commit a2628dc

Browse files
committed
Merge branch 'development' of https://github.com/kberg0/o3de-extras into MachineLearningGem
2 parents 7b10aec + 560d26d commit a2628dc

File tree

279 files changed

+47414
-1674
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

279 files changed

+47414
-1674
lines changed

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,6 @@ Templates/Ros2FleetRobotTemplate/docs/images/*.png filter= diff= merge= -text
129129
Gems/ROS2/docs/**/*.png -filter -diff -merge
130130
Templates/Ros2ProjectTemplate/Screenshots/*.png filter= diff= merge= -text
131131
Templates/Ros2FleetRobotTemplate/Screenshots/*.png filter= diff= merge= -text
132+
Templates/Ros2RoboticManipulationTemplate/Screenshots/*.png filter= diff= merge= -text
133+
132134
*.pgm filter=lfs diff=lfs merge=lfs -text

Gems/OpenXRVk/Code/Include/OpenXRVk/OpenXRVkDevice.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <XR/XRDevice.h>
1212
#include <XR/XRSwapChain.h>
1313
#include <OpenXRVk_Platform.h>
14+
#include <Atom/RHI.Reflect/Vulkan/XRVkDescriptors.h>
1415

1516
namespace OpenXRVk
1617
{
@@ -45,6 +46,9 @@ namespace OpenXRVk
4546
//! Get the native physical device
4647
VkPhysicalDevice GetNativePhysicalDevice() const;
4748

49+
//! Returns the graphic binding for a hardware queue
50+
const AZ::Vulkan::XRDeviceDescriptor::GraphicsBinding& GetGraphicsBinding(AZ::RHI::HardwareQueueClass queueClass) const;
51+
4852
//! Reserve space for appropriate number of views
4953
void InitXrViews(uint32_t numViews);
5054

@@ -69,6 +73,7 @@ namespace OpenXRVk
6973

7074
VkDevice m_xrVkDevice = VK_NULL_HANDLE;
7175
VkPhysicalDevice m_xrVkPhysicalDevice = VK_NULL_HANDLE;
76+
AZStd::array<AZ::Vulkan::XRDeviceDescriptor::GraphicsBinding, AZ::RHI::HardwareQueueClassCount> m_xrQueueBinding;
7277
XrFrameState m_frameState{ XR_TYPE_FRAME_STATE };
7378
AZStd::vector<XrCompositionLayerBaseHeader*> m_xrLayers;
7479
XrCompositionLayerProjection m_xrLayer{ XR_TYPE_COMPOSITION_LAYER_PROJECTION };

Gems/OpenXRVk/Code/Include/OpenXRVk/OpenXRVkSystemComponent.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#pragma once
1010

1111
#include <XR/XRFactory.h>
12+
#include <OpenXRVk/OpenXRVkInstance.h>
1213
#include <AzCore/Component/Component.h>
1314

1415
namespace OpenXRVk
@@ -61,6 +62,6 @@ namespace OpenXRVk
6162
///////////////////////////////////////////////////////////////////
6263

6364
private:
64-
XR::Ptr<XR::Instance> m_instance;
65+
XR::Ptr<OpenXRVk::Instance> m_instance;
6566
};
6667
}

Gems/OpenXRVk/Code/Source/OpenXRVkDevice.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include <OpenXRVk/OpenXRVkUtils.h>
1515
#include <OpenXRVkCommon.h>
1616
#include <Atom/RHI.Reflect/VkAllocator.h>
17-
#include <Atom/RHI.Reflect/Vulkan/XRVkDescriptors.h>
1817
#include <AzCore/Casting/numeric_cast.h>
1918

2019
namespace OpenXRVk
@@ -29,6 +28,7 @@ namespace OpenXRVk
2928
AZ::Vulkan::XRDeviceDescriptor* xrDeviceDescriptor = static_cast<AZ::Vulkan::XRDeviceDescriptor*>(deviceDescriptor);
3029
m_xrVkDevice = xrDeviceDescriptor->m_inputData.m_xrVkDevice;
3130
m_xrVkPhysicalDevice = xrDeviceDescriptor->m_inputData.m_xrVkPhysicalDevice;
31+
m_xrQueueBinding = xrDeviceDescriptor->m_inputData.m_xrQueueBinding;
3232
return AZ::RHI::ResultCode::Success;
3333
}
3434

@@ -182,6 +182,11 @@ namespace OpenXRVk
182182
return m_xrVkPhysicalDevice;
183183
}
184184

185+
const AZ::Vulkan::XRDeviceDescriptor::GraphicsBinding& Device::GetGraphicsBinding(AZ::RHI::HardwareQueueClass queueClass) const
186+
{
187+
return m_xrQueueBinding[static_cast<uint32_t>(queueClass)];
188+
}
189+
185190
AZ::RHI::ResultCode Device::GetViewFov(AZ::u32 viewIndex, AZ::RPI::FovData& outFovData) const
186191
{
187192
if(viewIndex < m_projectionLayerViews.size())

Gems/OpenXRVk/Code/Source/OpenXRVkSession.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,19 @@ namespace OpenXRVk
2424
return aznew Session;
2525
}
2626

27-
AZ::RHI::ResultCode Session::InitInternal(AZ::RHI::XRSessionDescriptor* descriptor)
27+
AZ::RHI::ResultCode Session::InitInternal([[maybe_unused]] AZ::RHI::XRSessionDescriptor* descriptor)
2828
{
29-
AZ::Vulkan::XRSessionDescriptor* sessionDescriptor = static_cast<AZ::Vulkan::XRSessionDescriptor*>(descriptor);
3029
Instance* xrVkInstance = static_cast<Instance*>(GetDescriptor().m_instance.get());
3130
Device* xrVkDevice = static_cast<Device*>(GetDescriptor().m_device.get());
31+
auto graphicBinding = xrVkDevice->GetGraphicsBinding(AZ::RHI::HardwareQueueClass::Graphics);
3232

3333
m_xrInstance = xrVkInstance->GetXRInstance();
3434
AZ_Printf("OpenXRVk", "Creating session...\n");
3535
m_graphicsBinding.instance = xrVkInstance->GetNativeInstance();
3636
m_graphicsBinding.physicalDevice = xrVkDevice->GetNativePhysicalDevice();
3737
m_graphicsBinding.device = xrVkDevice->GetNativeDevice();
38-
m_graphicsBinding.queueFamilyIndex = sessionDescriptor->m_inputData.m_graphicsBinding.m_queueFamilyIndex;
39-
m_graphicsBinding.queueIndex = sessionDescriptor->m_inputData.m_graphicsBinding.m_queueIndex;
38+
m_graphicsBinding.queueFamilyIndex = graphicBinding.m_queueFamilyIndex;
39+
m_graphicsBinding.queueIndex = graphicBinding.m_queueIndex;
4040

4141
AZ_Assert(m_xrInstance != XR_NULL_HANDLE, "XR instance is null.");
4242
AZ_Assert(m_session == XR_NULL_HANDLE, "XR session is already initialized.");

Gems/OpenXRVk/Code/Source/OpenXRVkSystemComponent.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ namespace OpenXRVk
8484
{
8585
if (XR::IsOpenXREnabled())
8686
{
87-
m_instance = CreateInstance();
87+
m_instance = AZStd::static_pointer_cast<OpenXRVk::Instance>(CreateInstance());
8888
//Get the validation mode
8989
AZ::RHI::ValidationMode validationMode = AZ::RHI::ValidationMode::Disabled;
9090
AZ::RHI::FactoryManagerBus::BroadcastResult(validationMode, &AZ::RHI::FactoryManagerRequest::DetermineValidationMode);

Gems/ROS2/Code/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ ly_add_target(
6464
Gem::Atom_RPI.Public
6565
Gem::Atom_Feature_Common.Static
6666
Gem::Atom_Component_DebugCamera.Static
67-
Gem::AtomLyIntegration_CommonFeatures.Static
6867
Gem::StartingPointInput
6968
Gem::PhysX.Static
7069
Gem::LmbrCentral.API
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
/*
2+
* Copyright (c) Contributors to the Open 3D Engine Project.
3+
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
4+
*
5+
* SPDX-License-Identifier: Apache-2.0 OR MIT
6+
*
7+
*/
8+
9+
#pragma once
10+
11+
#include <ROS2/ROS2Bus.h>
12+
#include <ROS2/Sensor/Events/SensorEventSource.h>
13+
#include <ROS2/Sensor/SensorConfiguration.h>
14+
15+
namespace ROS2
16+
{
17+
namespace Internal
18+
{
19+
template<
20+
template<
21+
template<typename...>
22+
class, // EventType
23+
template<typename...>
24+
class, // EventHandlerType
25+
typename...> // Event parameters
26+
class C,
27+
class T>
28+
struct is_specialization_of : AZStd::false_type
29+
{
30+
};
31+
32+
template<
33+
template<
34+
template<typename...>
35+
class, // EventType
36+
template<typename...>
37+
class, // EventHandlerType
38+
typename...> // Event parameters
39+
class Base,
40+
template<typename...>
41+
class EventType,
42+
template<typename...>
43+
class EventHandlerType,
44+
typename... Args>
45+
struct is_specialization_of<Base, Base<EventType, EventHandlerType, Args...>> : AZStd::true_type
46+
{
47+
};
48+
} // namespace Internal
49+
50+
//! Class adapting event source (ROS2::SensorEventSource) to configurable working frequency. This is handled via adapted event, in
51+
//! a similar manner like it is done in SensorEventSource. EventSourceAdapter has its internal handler that connects to
52+
//! SensorEventSource source event, and signals adapted event according to frequency set (ROS2::EventSourceAdapter::SetFrequency).
53+
//! User can connect to this event using ROS2::EventSourceAdapter::ConnectToAdaptedEvent method. This class should be used, instead
54+
//! of using directly a class derived from SensorEventSource, when specific working frequency is required. Following this path, user can
55+
//! still use source event - ROS2::EventSourceAdapter::ConnectToSourceEvent. This template has to be resolved using a class derived from
56+
//! SensorEventSource specialization.
57+
//! @see ROS2::SensorEventSource
58+
template<class EventSourceT>
59+
class EventSourceAdapter
60+
{
61+
public:
62+
// Require non-abstract type derived from SensorEventSource specialization.
63+
static_assert(Internal::is_specialization_of<SensorEventSource, typename EventSourceT::SourceBaseType>::value);
64+
static_assert(AZStd::is_base_of<typename EventSourceT::SourceBaseType, EventSourceT>::value);
65+
static_assert(AZStd::is_abstract<EventSourceT>::value == false);
66+
67+
static void Reflect(AZ::ReflectContext* context)
68+
{
69+
EventSourceT::Reflect(context);
70+
71+
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
72+
{
73+
serializeContext->Class<EventSourceAdapter<EventSourceT>>()
74+
->Version(1)
75+
->Field("Adapted frequency", &EventSourceAdapter<EventSourceT>::m_adaptedFrequency)
76+
->Field("Event source configuration", &EventSourceAdapter<EventSourceT>::m_eventSource);
77+
78+
if (auto* editContext = serializeContext->GetEditContext())
79+
{
80+
editContext
81+
->Class<EventSourceAdapter<EventSourceT>>(
82+
"Event Source Adapter", "Adapts sensor event source to specified working frequency")
83+
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
84+
->ElementAttribute(AZ::Edit::Attributes::AutoExpand, true)
85+
->DataElement(
86+
AZ::Edit::UIHandlers::Default,
87+
&EventSourceAdapter<EventSourceT>::m_adaptedFrequency,
88+
"Adapted frequency",
89+
"Adapter event signalling frequency");
90+
}
91+
}
92+
}
93+
94+
//! Starts event source adapter - assigns internal adapted event handler and starts managed event source. Adapted frequency can be
95+
//! set using ROS2::EventSourceAdapter::SetFrequency method.
96+
void Start()
97+
{
98+
m_sourceAdaptingEventHandler = typename EventSourceT::SourceEventHandlerType(
99+
[this](auto&&... args)
100+
{
101+
const float sourceDeltaTime = m_eventSource.GetDeltaTime(AZStd::forward<decltype(args)>(args)...);
102+
m_adaptedDeltaTime += sourceDeltaTime;
103+
104+
if (!IsPublicationDeadline(sourceDeltaTime))
105+
{
106+
return;
107+
}
108+
109+
m_sensorAdaptedEvent.Signal(m_adaptedDeltaTime, AZStd::forward<decltype(args)>(args)...);
110+
m_adaptedDeltaTime = 0.0f;
111+
});
112+
m_eventSource.ConnectToSourceEvent(m_sourceAdaptingEventHandler);
113+
m_eventSource.Start();
114+
}
115+
116+
//! Stops event source adapter - stops event source and disconnects internal adapted event handler from source event. If it will be
117+
//! necessary, this implementation allows multiple consecutive calls of Start / Stop, however user must also investigate specific
118+
//! event source implementation with such case in mind.
119+
void Stop()
120+
{
121+
m_eventSource.Stop();
122+
m_sourceAdaptingEventHandler.Disconnect();
123+
}
124+
125+
//! Sets adapter working frequency. By design, adapter will not work correctly, if this frequency will be greater than used event
126+
//! source frequency - e.g. adapter will be requested to work in 60Hz, when using event source working in 30Hz. In general, adapted
127+
//! frequency should be equal or lower than event source frequency - this is forced internally
128+
//! (ROS2::EventSourceAdapter::IsPublicationDeadline). Optimal (highest precision in timing events) working conditions take place
129+
//! when event source frequency is an integer multiple of adapted frequency.
130+
//! @param adaptedFrequency Adapter working frequency. When set to zero or less adapter will be assumed to work in 1Hz.
131+
void SetFrequency(float adaptedFrequency)
132+
{
133+
m_adaptedFrequency = adaptedFrequency;
134+
}
135+
136+
//! Connects given event handler to source event (ROS2::SensorEventSource). That event is signalled regardless of adapted frequency
137+
//! set for event source adapter (ROS2::EventSourceAdapter::SetFrequency). Its frequency depends only on specific event source
138+
//! implementation. If different working frequency is required (main purpose of ROS2::EventSourceAdapter), user should see
139+
//! ROS2::EventSourceAdapter::ConnectToAdaptedEvent method.
140+
//! @param sourceEventHandler Event handler for source event (frequency not managed by event source adapter).
141+
//! @see ROS2::SensorEventSource
142+
void ConnectToSourceEvent(typename EventSourceT::SourceEventHandlerType& sourceEventHandler)
143+
{
144+
m_eventSource.ConnectToSourceEvent(sourceEventHandler);
145+
}
146+
147+
//! Connects given event handler to adapted event (ROS2::EventSourceAdapter). This event is signalled with a frequency set with
148+
//! ROS2::EventSourceAdapter::SetFrequency method.
149+
//! @param adaptedEventHandler Event handler for adapted event.
150+
void ConnectToAdaptedEvent(typename EventSourceT::AdaptedEventHandlerType& adaptedEventHandler)
151+
{
152+
adaptedEventHandler.Connect(m_sensorAdaptedEvent);
153+
}
154+
155+
private:
156+
//! Uses:
157+
//! - internal tick counter,
158+
//! - last delta time of event source and
159+
//! - frequency set for adapter
160+
//! to support managing calls from event source. In other words, uses delta time of event source to calculate average number of
161+
//! source event calls per adapted event call.
162+
//! @param sourceDeltaTime Delta time of event source.
163+
//! @return Whether it is time to signal adapted event.
164+
[[nodiscard]] bool IsPublicationDeadline(float sourceDeltaTime)
165+
{
166+
if (--m_tickCounter > 0)
167+
{
168+
return false;
169+
}
170+
171+
const float sourceFrequencyEstimation = 1.0f / sourceDeltaTime;
172+
const float numberOfFrames =
173+
m_adaptedFrequency <= sourceFrequencyEstimation ? (sourceFrequencyEstimation / m_adaptedFrequency) : 1.0f;
174+
m_tickCounter = aznumeric_cast<int>(AZStd::round(numberOfFrames));
175+
return true;
176+
}
177+
178+
EventSourceT m_eventSource{}; ///< Event source managed by this adapter.
179+
180+
//! Event handler for adapting event source to specific frequency.
181+
typename EventSourceT::SourceEventHandlerType m_sourceAdaptingEventHandler{};
182+
183+
//! Adapted event that is called with specific frequency.
184+
typename EventSourceT::AdaptedEventType m_sensorAdaptedEvent{};
185+
186+
float m_adaptedFrequency{ 30.0f }; ///< Adapted frequency value.
187+
float m_adaptedDeltaTime{ 0.0f }; ///< Accumulator for calculating adapted delta time.
188+
int m_tickCounter{ 0 }; ///< Internal counter for controlling adapter frequency.
189+
};
190+
191+
AZ_TYPE_INFO_TEMPLATE(EventSourceAdapter, "{DC8BB5F7-8E0E-42A1-BD82-5FCD9D31B9DD}", AZ_TYPE_INFO_CLASS)
192+
} // namespace ROS2
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) Contributors to the Open 3D Engine Project.
3+
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
4+
*
5+
* SPDX-License-Identifier: Apache-2.0 OR MIT
6+
*
7+
*/
8+
9+
#pragma once
10+
11+
#include <AzCore/EBus/OrderedEvent.h>
12+
#include <AzFramework/Physics/Common/PhysicsEvents.h>
13+
#include <AzFramework/Physics/Common/PhysicsTypes.h>
14+
#include <ROS2/Sensor/Events/SensorEventSource.h>
15+
16+
namespace ROS2
17+
{
18+
//! Class implementing physics callbacks as sensor event source. Source event (ROS2::SensorEventSource) is signalled based on scene
19+
//! simulation finish event.
20+
//! @note The working frequency of this event source can be changed through engine settings (physics simulation delta).
21+
//! @see ROS2::SensorEventSource
22+
class PhysicsBasedSource final : public SensorEventSource<AZ::OrderedEvent, AZ::OrderedEventHandler, AzPhysics::SceneHandle, float>
23+
{
24+
public:
25+
AZ_TYPE_INFO(PhysicsBasedSource, "{48BB21A8-F14E-4869-95DC-28EEA279Cf53}");
26+
static void Reflect(AZ::ReflectContext* context);
27+
28+
// Overrides of ROS2::SensorEventSource.
29+
void Start() override;
30+
void Stop() override;
31+
[[nodiscard]] float GetDeltaTime(AzPhysics::SceneHandle sceneHandle, float deltaTime) const override;
32+
33+
private:
34+
AzPhysics::SceneEvents::OnSceneSimulationFinishHandler m_onSceneSimulationEventHandler; ///< Handler for physics callback.
35+
};
36+
} // namespace ROS2

0 commit comments

Comments
 (0)