Skip to content

Commit de956bb

Browse files
committed
added feature to get statistics and change app fps
Signed-off-by: Michał Pełka <[email protected]>
1 parent 2624b33 commit de956bb

File tree

2 files changed

+94
-4
lines changed

2 files changed

+94
-4
lines changed

Gems/SensorDebug/Code/Source/Clients/SensorDebugSystemComponent.cpp

Lines changed: 85 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include <SensorDebug/SensorDebugTypeIds.h>
55

66
#include <AzCore/Serialization/SerializeContext.h>
7-
7+
#include <AzFramework/Components/ConsoleBus.h>
88
namespace SensorDebug
99
{
1010
AZ_COMPONENT_IMPL(SensorDebugSystemComponent, "SensorDebugSystemComponent", SensorDebugSystemComponentTypeId);
@@ -20,10 +20,12 @@ namespace SensorDebug
2020
void SensorDebugSystemComponent::Activate()
2121
{
2222
ImGui::ImGuiUpdateListenerBus::Handler::BusConnect();
23+
AZ::TickBus::Handler::BusConnect();
2324
}
2425

2526
void SensorDebugSystemComponent::Deactivate()
2627
{
28+
AZ::TickBus::Handler::BusDisconnect();
2729
ImGui::ImGuiUpdateListenerBus::Handler::BusDisconnect();
2830
}
2931

@@ -129,6 +131,41 @@ namespace SensorDebug
129131
void SensorDebugSystemComponent::OnImGuiUpdate()
130132
{
131133
ImGui::Begin("ROS2 SensorDebugger");
134+
135+
ImGui::InputFloat("Application Max FPS", &m_maxFPS);
136+
ImGui::SameLine();
137+
if (ImGui::Button("Set sys_MaxFPS"))
138+
{
139+
//disable vsync
140+
AZStd::string commandVsync = AZStd::string::format("vsync_interval=0");
141+
AzFramework::ConsoleRequestBus::Broadcast(&AzFramework::ConsoleRequests::ExecuteConsoleCommand, commandVsync.c_str());
142+
AZStd::string commandMaxFps = AZStd::string::format("sys_MaxFPS=%f", m_maxFPS);
143+
AzFramework::ConsoleRequestBus::Broadcast(&AzFramework::ConsoleRequests::ExecuteConsoleCommand, commandMaxFps.c_str());
144+
m_appFrequencies.clear();
145+
}
146+
147+
float freqencySum = 0.0f;
148+
for (const auto& freq : m_appFrequencies)
149+
{
150+
freqencySum += freq;
151+
}
152+
const float averageFrequency = freqencySum / static_cast<float>(m_appFrequencies.size());
153+
// compute std deviation
154+
float variance = 0.0f;
155+
for (const auto& freq : m_appFrequencies)
156+
{
157+
variance += (freq - averageFrequency) * (freq - averageFrequency);
158+
}
159+
float stdDeviation = sqrt(variance / static_cast<float>(m_appFrequencies.size()));
160+
ImGui::Separator();
161+
ImGui::PlotHistogram("App Actual Frequency", m_appFrequencies.data(), static_cast<int>(m_appFrequencies.size()), 0);
162+
ImGui::Text("App Actual Frequency: %.2f Hz [ std_dev = %.2f ]", averageFrequency, stdDeviation);
163+
ImGui::SameLine();
164+
if (ImGui::Button("reset stats"))
165+
{
166+
m_appFrequencies.clear();
167+
}
168+
ImGui::Separator();
132169
if (ImGui::Button("Refresh with EnumerateHandlers(o3de bus API)"))
133170
{
134171
FindSensorsWithBusAPI();
@@ -178,7 +215,7 @@ namespace SensorDebug
178215
{
179216
FindSensorsWithGivenType(ROS2::ROS2OdometrySensorComponent);
180217
}
181-
218+
ImGui::InputInt("History Size", &m_historySize);
182219
for (auto& sensorEntity : m_sensorEntities)
183220
{
184221
ImGui::Separator();
@@ -189,7 +226,42 @@ namespace SensorDebug
189226
float frequency = 0.0f;
190227
ROS2::SensorConfigurationRequestBus::EventResult(
191228
frequency, sensorEntity, &ROS2::SensorConfigurationRequest::GetEffectiveFrequency);
192-
ImGui::Text("%s : %s effective Freq: %f Hz", entityName.c_str(), sensorName.c_str(), frequency);
229+
230+
m_sensorFrequencyHistory[sensorEntity].push_back(frequency);
231+
auto &sensorFrequencyHistory = m_sensorFrequencyHistory[sensorEntity];
232+
if (sensorFrequencyHistory.size() > m_historySize)
233+
{
234+
sensorFrequencyHistory.erase(sensorFrequencyHistory.begin());
235+
}
236+
float freqencySum = 0.0f;
237+
for (const auto& freq : sensorFrequencyHistory)
238+
{
239+
freqencySum += freq;
240+
}
241+
const float averageFrequency = freqencySum / static_cast<float>(sensorFrequencyHistory.size());
242+
// compute std deviation
243+
float variance = 0.0f;
244+
for (const auto& freq : sensorFrequencyHistory)
245+
{
246+
variance += (freq - averageFrequency) * (freq - averageFrequency);
247+
}
248+
float stdDeviation = sqrt(variance / static_cast<float>(sensorFrequencyHistory.size()));
249+
const AZStd::string histogramNameWithCookie = AZStd::string::format("Histogram%s", cookie.c_str());
250+
251+
ImGui::PlotHistogram(
252+
histogramNameWithCookie.c_str(), sensorFrequencyHistory.data(), static_cast<int>(sensorFrequencyHistory.size()), 0);
253+
ImGui::SameLine();
254+
const AZStd::string resetButton = AZStd::string::format("reset stats%s", cookie.c_str());
255+
if (ImGui::Button(resetButton.c_str()))
256+
{
257+
sensorFrequencyHistory.clear();
258+
}
259+
ImGui::Text(
260+
"%s : %s effective Freq: %.2f Hz [ std_dev = %.2f ]",
261+
entityName.c_str(),
262+
sensorName.c_str(),
263+
averageFrequency,
264+
stdDeviation);
193265

194266
AZStd::string buttonNameEna = AZStd::string::format("Enable%s", cookie.c_str());
195267
AZStd::string buttonNameDis = AZStd::string::format("Disable%s", cookie.c_str());
@@ -230,7 +302,7 @@ namespace SensorDebug
230302
ROS2::SensorConfigurationRequestBus::Event(sensorEntity, &ROS2::SensorConfigurationRequest::SetVisualizeEnabled, false);
231303
}
232304
AZStd::string freqName = AZStd::string::format("Frequency%s", cookie.c_str());
233-
ImGui::DragFloat(freqName.c_str(), &m_sensorFrequencies[sensorEntity], 0.1f, 0.1f, 500.0f);
305+
ImGui::InputFloat(freqName.c_str(), &m_sensorFrequencies[sensorEntity]);
234306
ImGui::SameLine();
235307
AZStd::string buttonSetFreq = AZStd::string::format("Set Frequency%s", cookie.c_str());
236308
if (ImGui::Button(buttonSetFreq.c_str()))
@@ -242,4 +314,13 @@ namespace SensorDebug
242314

243315
ImGui::End();
244316
}
317+
318+
void SensorDebugSystemComponent::OnTick(float deltaTime, AZ::ScriptTimePoint time)
319+
{
320+
m_appFrequencies.push_back(1.0f / deltaTime);
321+
if (m_appFrequencies.size() > m_historySize)
322+
{
323+
m_appFrequencies.erase(m_appFrequencies.begin());
324+
}
325+
}
245326
} // namespace SensorDebug

Gems/SensorDebug/Code/Source/Clients/SensorDebugSystemComponent.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@
1010
#include <ROS2/Sensor/SensorConfigurationRequestBus.h>
1111
#include <ROS2/Sensor/SensorHelper.h>
1212
#include <imgui/imgui.h>
13+
#include <AzCore/Component/TickBus.h>
1314
namespace SensorDebug
1415
{
1516
class SensorDebugSystemComponent
1617
: public AZ::Component
1718
, public ImGui::ImGuiUpdateListenerBus::Handler
19+
, private AZ::TickBus::Handler
1820
{
1921
public:
2022
AZ_COMPONENT_DECL(SensorDebugSystemComponent);
@@ -35,12 +37,19 @@ namespace SensorDebug
3537
void ClearSensors();
3638

3739
private:
40+
// AZ::TickBus::Handler interface implementation
41+
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
42+
3843
void FindSensorsWithBusAPI();
3944
void FindSensorsWithComponentAPI();
4045
void FindSensorsWithGivenType(const char* typeId);
4146
AZStd::vector<AZ::EntityComponentIdPair> m_sensorEntities;
47+
AZStd::unordered_map<AZ::EntityComponentIdPair, AZStd::vector<float>> m_sensorFrequencyHistory;
4248
AZStd::unordered_map<AZ::EntityComponentIdPair, AZStd::string> m_sensorNames;
4349
AZStd::unordered_map<AZ::EntityComponentIdPair, AZStd::string> m_entitiesNames;
4450
AZStd::unordered_map<AZ::EntityComponentIdPair, float> m_sensorFrequencies;
51+
AZStd::vector<float> m_appFrequencies;
52+
float m_maxFPS = 60.0f;
53+
int m_historySize = 1000;
4554
};
4655
} // namespace SensorDebug

0 commit comments

Comments
 (0)