FPSCounter.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package VisionX::Tools
19 * @author Kai Welke (kai dot welke at kit dot edu)
20 * @date 2011
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24
25// *******************************************************
26// include
27// *******************************************************
28#include "FPSCounter.h"
29
30#include <cfloat>
31
32#include <sys/time.h>
33#include <unistd.h> // for usleep
34
35namespace visionx
36{
37 // *******************************************************
38 // construction / destruction
39 // *******************************************************
40 FPSCounter::FPSCounter(int nDelayFrames)
41 {
42 m_nDelayFrames = nDelayFrames;
43
44 reset();
45 }
46
47 // *******************************************************
48 // control
49 // *******************************************************
50 void
52 {
53 // init members
54 m_nIntervalTime = 0;
55
56 m_fFPS = 0.0f;
57 m_nUpdates = 0;
58 m_fMinCycleTimeMS = FLT_MAX;
59 m_fMaxCycleTimeMS = -FLT_MAX;
60 }
61
62 void
64 {
65 // calculate current cycle time
66 int nCycleTime = calculateTimeDiff(m_nCycleSec, m_nCycleUSec, true);
67
68 // update members with time diff
69 updateMembers(nCycleTime);
70
71 // increment update counter
72 m_nUpdates++;
73 }
74
75 void
77 {
78 // TODO proper implementation
79 // calculate current cycle time
80 // int nCycleTime = calculateTimeDiff(m_nCycleSec, m_nCycleUSec, false);
81
82 // update members with time diff
83 // updateMembers(nCycleTime);
84 }
85
86 void
87 FPSCounter::assureFPS(float fFrameRate)
88 {
89 // first run is not valid
90 bool bValidTime = (m_nUpdates != 0);
91 int nOverallCycleTime = (1.0f / fFrameRate) * 1000000;
92
93 if (bValidTime)
94 {
95 // calculate target cycle time
96 int nWantedUSec = (1.0f / fFrameRate) * 1000000;
97
98 int nTimeDiff;
99
100 // wait until wanted cycle time is reached
101 do
102 {
103 nTimeDiff = calculateTimeDiff(m_nCycleSec, m_nCycleUSec);
104 usleep(1);
105 } while (nTimeDiff < nWantedUSec);
106
107 // update time stamp
108 nOverallCycleTime = calculateTimeDiff(m_nCycleSec, m_nCycleUSec, true);
109 }
110
111 calculateTimeDiff(m_nCycleSec, m_nCycleUSec, true);
112 updateMembers(nOverallCycleTime);
113
114 // increment update counter
115 m_nUpdates++;
116 }
117
118 // *******************************************************
119 // member access
120 // *******************************************************
121 bool
123 {
124 return m_nUpdates > m_nDelayFrames;
125 }
126
127 int
129 {
130 return m_nUpdates;
131 }
132
133 float
135 {
136 if (m_nUpdates <= m_nDelayFrames)
137 {
138 return 0.0f;
139 }
140
141 return m_fFPS;
142 }
143
144 float
146 {
147 if (m_nUpdates <= 10)
148 {
149 return 0.0f;
150 }
151
152 float fMeanTimeMS = 0.0f;
153
154 for (int i = 0; i < 10; i++)
155 {
156 fMeanTimeMS += m_fLastCycleTimesMS[i];
157 }
158
159 return fMeanTimeMS / 10;
160 }
161
162 float
164 {
165 if (m_nUpdates <= 1)
166 {
167 return 0.0f;
168 }
169
170 return m_fMinCycleTimeMS;
171 }
172
173 float
175 {
176 if (m_nUpdates <= 1)
177 {
178 return 0.0f;
179 }
180
181 return m_fMaxCycleTimeMS;
182 }
183
184 // *******************************************************
185 // private methods
186 // *******************************************************
187 void
188 FPSCounter::updateMembers(int nCycleTime)
189 {
190 // first run is not valid
191 bool bValidTime = (m_nUpdates != 0);
192
193 // update statistics
194 recalculateFPS(nCycleTime);
195
196 if (bValidTime)
197 {
198 recalculateStats(nCycleTime);
199 }
200 }
201
202 void
203 FPSCounter::recalculateFPS(int nCycleUSec)
204 {
205 m_nIntervalTime += nCycleUSec;
206
207 // only recalculate over some time
208 if ((m_nUpdates % m_nDelayFrames == 0) && (m_nUpdates != 0))
209 {
210 // calculate fps
211 float fTimeDiff = m_nIntervalTime / 1000000.0f;
212 m_fFPS = (1.0f / fTimeDiff) * m_nDelayFrames;
213 m_nIntervalTime = 0;
214 }
215 }
216
217 void
218 FPSCounter::recalculateStats(int nCycleUSec)
219 {
220 float fTimeMS = float(nCycleUSec) / 1000.0f;
221
222 if (fTimeMS < m_fMinCycleTimeMS)
223 {
224 m_fMinCycleTimeMS = fTimeMS;
225 }
226
227 if (fTimeMS > m_fMaxCycleTimeMS)
228 {
229 m_fMaxCycleTimeMS = fTimeMS;
230 }
231
232 m_fLastCycleTimesMS[(m_nUpdates - 1) % 10] = fTimeMS;
233 }
234
235 // calculate difference between given time stamp and current time
236 int
237 FPSCounter::calculateTimeDiff(long& nSec, long& nUSec, bool bSetTime)
238 {
239 timeval t;
240 gettimeofday(&t, nullptr);
241 int nTimeDiff = (t.tv_sec - nSec) * 1000000 + ((int)t.tv_usec - nUSec);
242
243 if (bSetTime)
244 {
245 nSec = t.tv_sec;
246 nUSec = t.tv_usec;
247 }
248 return nTimeDiff;
249 }
250} // namespace visionx
#define float
Definition 16_Level.h:22
void assureFPS(float fFrameRate)
Synchronize to FPS.
float getMeanCycleTimeMS()
Get mean cycle time over last 10 frames.
void recalculate()
recalculates the FPS statistics
float getMinCycleTimeMS()
Get minimum cycle time since start.
int getUpdates()
Get number of updates.
float getFPS()
Get frames per second.
FPSCounter(int nDelayFrames=10)
Constructs a new FPS counter.
void update()
Updates the FPS counter.
void reset()
Resets the FPS counter to its initial state.
bool getValid()
Get if calculated values are valid.
float getMaxCycleTimeMS()
Get maximum cycle time since start.
ArmarX headers.