4
4
#include < SensorDebug/SensorDebugTypeIds.h>
5
5
6
6
#include < AzCore/Serialization/SerializeContext.h>
7
-
7
+ # include < AzFramework/Components/ConsoleBus.h >
8
8
namespace SensorDebug
9
9
{
10
10
AZ_COMPONENT_IMPL (SensorDebugSystemComponent, " SensorDebugSystemComponent" , SensorDebugSystemComponentTypeId);
@@ -20,10 +20,12 @@ namespace SensorDebug
20
20
void SensorDebugSystemComponent::Activate ()
21
21
{
22
22
ImGui::ImGuiUpdateListenerBus::Handler::BusConnect ();
23
+ AZ::TickBus::Handler::BusConnect ();
23
24
}
24
25
25
26
void SensorDebugSystemComponent::Deactivate ()
26
27
{
28
+ AZ::TickBus::Handler::BusDisconnect ();
27
29
ImGui::ImGuiUpdateListenerBus::Handler::BusDisconnect ();
28
30
}
29
31
@@ -129,6 +131,41 @@ namespace SensorDebug
129
131
void SensorDebugSystemComponent::OnImGuiUpdate ()
130
132
{
131
133
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 ();
132
169
if (ImGui::Button (" Refresh with EnumerateHandlers(o3de bus API)" ))
133
170
{
134
171
FindSensorsWithBusAPI ();
@@ -178,7 +215,7 @@ namespace SensorDebug
178
215
{
179
216
FindSensorsWithGivenType (ROS2::ROS2OdometrySensorComponent);
180
217
}
181
-
218
+ ImGui::InputInt ( " History Size " , &m_historySize);
182
219
for (auto & sensorEntity : m_sensorEntities)
183
220
{
184
221
ImGui::Separator ();
@@ -189,7 +226,42 @@ namespace SensorDebug
189
226
float frequency = 0 .0f ;
190
227
ROS2::SensorConfigurationRequestBus::EventResult (
191
228
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);
193
265
194
266
AZStd::string buttonNameEna = AZStd::string::format (" Enable%s" , cookie.c_str ());
195
267
AZStd::string buttonNameDis = AZStd::string::format (" Disable%s" , cookie.c_str ());
@@ -230,7 +302,7 @@ namespace SensorDebug
230
302
ROS2::SensorConfigurationRequestBus::Event (sensorEntity, &ROS2::SensorConfigurationRequest::SetVisualizeEnabled, false );
231
303
}
232
304
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]);
234
306
ImGui::SameLine ();
235
307
AZStd::string buttonSetFreq = AZStd::string::format (" Set Frequency%s" , cookie.c_str ());
236
308
if (ImGui::Button (buttonSetFreq.c_str ()))
@@ -242,4 +314,13 @@ namespace SensorDebug
242
314
243
315
ImGui::End ();
244
316
}
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
+ }
245
326
} // namespace SensorDebug
0 commit comments