Determining if 5 seconds have passed - c++

I'm trying to determine if five seconds have passed in a console application since the last time I checked. I think my logic is slightly off and I don't know how to resolve it.
My lastCheck variable is firstly 0 when the program begins. It's responsible for holding the "old time".
LastCheck is updated by CheckSeconds(), which gives it a new "old time"
If the LastCheck was equal to 1232323, and the now variable is currently equal to 1227323 then I would know 5000 milliseconds have passed. (in reality, the numbers are much greater than this)
Else, I don't want anything to happen, I want to wait until these five seconds have actually passed.
BACKEND
inline std::vector<int> CheckSeconds(int previous, int timeinseconds)
{
//check if a certain amount of seconds have passed.
int now = GetTickCount();
int timepassed = 0;
std::vector<int> trueandnewtime;
//if the current time minus the old time is greater than 5000, then that means more than 5000 milliseoncds passed.
//therefore the timepassed is true.
if (now - previous > 5000)
timepassed = 1;
trueandnewtime.push_back(timepassed);
trueandnewtime.push_back(now);
return trueandnewtime;
}
FRONTEND
storage = CheckSeconds(LastCheck, 5);
LastCheck = storage.at(1);
if (storage.at(0) == 1)
{
....blahblahblah.....
}
Anyone know what I'm doing wrong? I must have a logic error somewhere or I'm being dumb.
Also worth noting, this code is in a while loop, getting constantly run at Sleep(60); It's a console application at the momemnt.
Appreciate any assistance.

Fixed it by putting the Lastcheck set into the loop.

Related

I can't make my function calculate how much time has passed and print stuff accordingly

bool IsGameEnded()
{
static int i = 0;
i++;
if (i == 10)
return true;
return false;
}
int main()
{
bool GameEnd = false;
float ElapsedTime = 0;
while(!GameEnd)
{
chrono::steady_clock::time_point StartingTime = chrono::steady_clock::now();
if (ElapsedTime > 10)
{
ElapsedTime = 0;
draw();
}
GameEnd = IsGameEnded();
chrono::steady_clock::time_point EndingTime = chrono::steady_clock::now();
ElapsedTime = ElapsedTime + chrono::duration_cast<chrono::milliseconds>(EndingTime - StartingTime).count();
}
return 0;
}
I wan't to make a snake game. It will be based on time. For example screen will update every 5 seconds or so. For that I used chrono library. I am not used to this trying o learn it so I might have missed something obvious. But the problem is main function doesn't get get into the if block. So it draws nothing to the console.
I tried debugging (with running line by line). It is not actually like a running program becasue time intervals get long but it enters if block every time. Also if I make the if condition 2 nanoseconds it also works but since cout function can not print so fast I need it to be a lot longer than that. While Debugging I also realised that "StartingTime" and "EndingTime" variables don't get initiated (unless I directly stop on them) . The interesting part is If ı add cout after if block, after a while program starts entering the If block.
When you do:
chrono::duration_cast<chrono::milliseconds>(EndingTime - StartingTime).count();
not enough time has passed, and the count of milliseconds always returns 0. This means you always add 0 to ElapsedTime and it never crosses 10.
One fix is to use a smaller resolution:
chrono::duration_cast<chrono::nanoseconds>(EndingTime - StartingTime).count();
as you mentioned in the question, and adjust the if condition appropriately.
However, the best fix would be to change ElapsedTime from a float to a chrono::duration (of the appropriate unit) since that is the unit that the variable represents. This would let you avoid having to do .count() on the duration as well.

It seems like ncurses is causing my loop to break early

I'm running a program using ncurses with a loop that is supposed to generate a window for character movement, wait ~five seconds, clear the window, and start again. My thought is to have this be in a nested window that will do this ten times. However, after the first five seconds ends, the entire loop is broken and the program finishes.
int i=0;
while(i < 10)
{
playwin.makeWindow();
wtimeout(playwin.getWindow(), 0);
originalTime = time(NULL);
while(newTime < 5)
{
newTime = time(NULL);
newTime -= originalTime;
player.display();
playwin.drawWindow();
player.getMv();
}
wclear(playwin.getWindow());
i++;
}
I expect that the window gets made, the wtimeout function will stop the getMv function from blocking, the nested while loop will display the window and allow the player to move around. After about five seconds, I expect that while loop to end, the window to get cleared, the iterator to increase, and for the loop to start again.
However, after the nested while loop ends, the iterator is already at 10 (verified with printf), so the whole loop breaks.
However, after the nested while loop ends, the iterator is already at 10 (verified with printf), so the whole loop breaks.
there is no visible initialization of newtime, if its initial value (may be undefined if there is no init at all) is not less than 5 the while(newTime < 5)... is never executed because newTime never changes and i become quikly 10
If its initial value if less than 5 the while(newTime < 5)... is only executed one time because you do not reset its value after
Just add for instance newTime = 0; (or a value less than 5) before while(newTime < 5) ...
Before you enter the loop, originalTime is set to the current time.
As soon as you enter, newTime gets (probably) the same value.
You substract one from the other so newTime becomes 0.
It will therefore not enter the loop a second time.

algorithm for calculating a running clicks/second value (ala a speedometer)

I'm trying to figure out how to produce a running calculation of clicks per second (e.g. an app with a window I click on and it gives me a speedometer-like value of the 'speed' of my clicks in clicks per second). For some reason the algorithm is eluding me.
It's easy to figure out if I just want to figure out clicks per second if at each second I report how many clicks happened in the last second. But where it gets tricky is if there was one click in second 1, then 0 clicks in seconds 2-9 and 1 click in second 10. Presumably that would be .2 clicks per second--although really only if it was kept up and averaged out to that over time. If that click in second 10 was followed by 0 clicks for 40 seconds, then it should be 0 clicks/second, not .04 clicks/second.
So clearly I need some kind of window within which I'm willing to presume the clicks are part of a pattern, or at least associated with the last ones. But it's just not making sense to me.
I'm using openframeworks for this, so have an update() function that is called more than once/second (say 30x/sec), and have a mousePressed() function that allows me to increment a variable to track the clicks. i can use difftime() and time() to track whether I just crossed into a new second, and then use fmod() to figure out if I just crossed some larger interval.
Any suggestions are appreciated.
I think you want to calculate the running average of the clicks per second. You would use a circular buffer of counters of a length of say 30 for a 30 second window. The average clicks per second is the sum of the counters divided by 30.
An index points to the current counter, the index is incremented modulo 30 every second, and the counter at the new position is set to zero.
example:
const unsigned BUFFER_SIZE = 30;
unsigned counters[BUFFER_SIZE];
unsigned current = 0;
time_t last;
void init() {
time(&last);
}
void update() {
time_t now;
time(&now);
while (now - last >= 1) {
++last;
current = (current+1)%BUFFER_SIZE;
counters[current] = 0;
}
}
void mousePressed() {
++counters[current];
}
float average() {
float sum = 0;
for (int i = 0; i < BUFFER_SIZE; ++i) {
sum += counters[i];
}
return sum/BUFFER_SIZE;
}
This is pseudo code, but I think it will do what you are asking:
onUpdate() {
if (currentTime() - lastClickTime > idleTimeout) {
// reset the clickometer to zero
} else {
// calculate the speed
}
}
onMouseClick() {
lastClickTime = currentTime();
// and whatever else needs to happen
}
Basically you are just tracking the time of the last click, and making sure it happened within the idleTimeout, which you obviously have to define for some span of time.

Calculating moving average in C++

I am trying to calculate the moving average of a signal. The signal value ( a double ) is updated at random times.
I am looking for an efficient way to calculate it's time weighted average over a time window, in real time. I could do it my self, but it is more challenging than I thought.
Most of the resources I've found over the internet are calculating moving average of periodical signal, but mine updates at random time.
Does anyone know good resources for that ?
Thanks
The trick is the following: You get updates at random times via void update(int time, float value). However you also need to also track when an update falls off the time window, so you set an "alarm" which called at time + N which removes the previous update from being ever considered again in the computation.
If this happens in real-time you can request the operating system to make a call to a method void drop_off_oldest_update(int time) to be called at time + N
If this is a simulation, you cannot get help from the operating system and you need to do it manually. In a simulation you would call methods with the time supplied as an argument (which does not correlate with real time). However, a reasonable assumption is that the calls are guaranteed to be such that the time arguments are increasing. In this case you need to maintain a sorted list of alarm time values, and for each update and read call you check if the time argument is greater than the head of the alarm list. While it is greater you do the alarm related processing (drop off the oldest update), remove the head and check again until all alarms prior to the given time are processed. Then do the update call.
I have so far assumed it is obvious what you would do for the actual computation, but I will elaborate just in case. I assume you have a method float read (int time) that you use to read the values. The goal is to make this call as efficient as possible. So you do not compute the moving average every time the read method is called. Instead you precompute the value as of the last update or the last alarm, and "tweak" this value by a couple of floating point operations to account for the passage of time since the last update. (i. e. a constant number of operations except for perhaps processing a list of piled up alarms).
Hopefully this is clear -- this should be a quite simple algorithm and quite efficient.
Further optimization: one of the remaining problems is if a large number of updates happen within the time window, then there is a long time for which there are neither reads nor updates, and then a read or update comes along. In this case, the above algorithm will be inefficient in incrementally updating the value for each of the updates that is falling off. This is not necessary because we only care about the last update beyond the time window so if there is a way to efficiently drop off all older updates, it would help.
To do this, we can modify the algorithm to do a binary search of updates to find the most recent update before the time window. If there are relatively few updates that needs to be "dropped" then one can incrementally update the value for each dropped update. But if there are many updates that need to be dropped then one can recompute the value from scratch after dropping off the old updates.
Appendix on Incremental Computation: I should clarify what I mean by incremental computation above in the sentence "tweak" this value by a couple of floating point operations to account for the passage of time since the last update. Initial non-incremental computation:
start with
sum = 0;
updates_in_window = /* set of all updates within window */;
prior_update' = /* most recent update prior to window with timestamp tweaked to window beginning */;
relevant_updates = /* union of prior_update' and updates_in_window */,
then iterate over relevant_updates in order of increasing time:
for each update EXCEPT last {
sum += update.value * time_to_next_update;
},
and finally
moving_average = (sum + last_update * time_since_last_update) / window_length;.
Now if exactly one update falls off the window but no new updates arrive, adjust sum as:
sum -= prior_update'.value * time_to_next_update + first_update_in_last_window.value * time_from_first_update_to_new_window_beginning;
(note it is prior_update' which has its timestamp modified to start of last window beginning). And if exactly one update enters the window but no new updates fall off, adjust sum as:
sum += previously_most_recent_update.value * corresponding_time_to_next_update.
As should be obvious, this is a rough sketch but hopefully it shows how you can maintain the average such that it is O(1) operations per update on an amortized basis. But note further optimization in previous paragraph. Also note stability issues alluded to in an older answer, which means that floating point errors may accumulate over a large number of such incremental operations such that there is a divergence from the result of the full computation that is significant to the application.
If an approximation is OK and there's a minimum time between samples, you could try super-sampling. Have an array that represents evenly spaced time intervals that are shorter than the minimum, and at each time period store the latest sample that was received. The shorter the interval, the closer the average will be to the true value. The period should be no greater than half the minimum or there is a chance of missing a sample.
#include <map>
#include <iostream>
// Sample - the type of a single sample
// Date - the type of a time notation
// DateDiff - the type of difference of two Dates
template <class Sample, class Date, class DateDiff = Date>
class TWMA {
private:
typedef std::map<Date, Sample> qType;
const DateDiff windowSize; // The time width of the sampling window
qType samples; // A set of sample/date pairs
Sample average; // The answer
public:
// windowSize - The time width of the sampling window
TWMA(const DateDiff& windowSize) : windowSize(windowSize), average(0) {}
// Call this each time you receive a sample
void
Update(const Sample& sample, const Date& now) {
// First throw away all old data
Date then(now - windowSize);
samples.erase(samples.begin(), samples.upper_bound(then));
// Next add new data
samples[now] = sample;
// Compute average: note: this could move to Average(), depending upon
// precise user requirements.
Sample sum = Sample();
for(typename qType::iterator it = samples.begin();
it != samples.end();
++it) {
DateDiff duration(it->first - then);
sum += duration * it->second;
then = it->first;
}
average = sum / windowSize;
}
// Call this when you need the answer.
const Sample& Average() { return average; }
};
int main () {
TWMA<double, int> samples(10);
samples.Update(1, 1);
std::cout << samples.Average() << "\n"; // 1
samples.Update(1, 2);
std::cout << samples.Average() << "\n"; // 1
samples.Update(1, 3);
std::cout << samples.Average() << "\n"; // 1
samples.Update(10, 20);
std::cout << samples.Average() << "\n"; // 10
samples.Update(0, 25);
std::cout << samples.Average() << "\n"; // 5
samples.Update(0, 30);
std::cout << samples.Average() << "\n"; // 0
}
Note: Apparently this is not the way to approach this. Leaving it here for reference on what is wrong with this approach. Check the comments.
UPDATED - based on Oli's comment... not sure about the instability that he is talking about though.
Use a sorted map of "arrival times" against values. Upon arrival of a value add the arrival time to the sorted map along with it's value and update the moving average.
warning this is pseudo-code:
SortedMapType< int, double > timeValueMap;
void onArrival(double value)
{
timeValueMap.insert( (int)time(NULL), value);
}
//for example this runs every 10 seconds and the moving window is 120 seconds long
void recalcRunningAverage()
{
// you know that the oldest thing in the list is
// going to be 129.9999 seconds old
int expireTime = (int)time(NULL) - 120;
int removeFromTotal = 0;
MapIterType i;
for( i = timeValueMap.begin();
(i->first < expireTime || i != end) ; ++i )
{
}
// NOW REMOVE PAIRS TO LEFT OF i
// Below needs to apply your time-weighting to the remaining values
runningTotal = calculateRunningTotal(timeValueMap);
average = runningTotal/timeValueMap.size();
}
There... Not fully fleshed out but you get the idea.
Things to note:
As I said the above is pseudo code. You'll need to choose an appropriate map.
Don't remove the pairs as you iterate through as you will invalidate the iterator and will have to start again.
See Oli's comment below also.

delay loop output in C++

I have a while loop that runs in a do while loop. I need the while loop to run exactly every second no faster no slower. but i'm not sure how i would do that. this is the loop, off in its own function. I have heard of the sleep() function but I also have heard that it is not very accurate.
int min5()
{
int second = 00;
int minute = 0;
const int ZERO = 00;
do{
while (second <= 59){
if(minute == 5) break;
second += 1;
if(second == 60) minute += 1;
if(second == 60) second = ZERO;
if(second < 60) cout << "Current Time> "<< minute <<" : "<< second <<" \n";
}
} while (minute <= 5);
}
The best accuracy you can achieve is by using Operating System (OS) functions. You need to find the API that also has a callback function. The callback function is a function you write that the OS will call when the timer has expired.
Be aware that the OS may lose timing precision due to other tasks and activities that are running while your program is executing.
If you want a portable solution, you shouldn't expect high-precision timing. Usually, you only get that with a platform-dependent solution.
A portable (albeit not very CPU-efficient, nor particularly elegant) solution might make use of a function similar to this:
#include <ctime>
void wait_until_next_second()
{
time_t before = time(0);
while (difftime(time(0), before) < 1);
}
You'd then use this in your function like this:
int min5()
{
wait_until_next_second(); // synchronization (optional), so that the first
// subsequent call will not take less than 1 sec.
...
do
{
wait_until_next_second(); // waits approx. one second
while (...)
{
...
}
} while (...)
}
Some further comments on your code:
Your code gets into an endless loop once minute reaches the value 5.
Are you aware that 00 denotes an octal (radix 8) number (due to the leading zero)? It doesn't matter in this case, but be careful with numbers such as 017. This is decimal 15, not 17!
You could incorporate the seconds++ right into the while loop's condition: while (seconds++ <= 59) ...
I think in this case, it would be better to insert endl into the cout stream, since that will flush it, while inserting "\n" won't flush the stream. It doesn't truly matter here, but your intent seems to be to always see the current time on cout; if you don't flush the stream, you're not actually guaranteed to see the time message immediately.
As someone else posted, your OS may provide some kind of alarm or timer functionality. You should try to use this kind of thing rather than coding your own polling loop. Polling the time means you need to be context switched in every second, which keeps your code running when the system could be doing other stuff. In this case you interrupt someone else 300 times just to say "are we done yet".
Also, you should never make assumptions about the duration of a sleep - even if you had a real time OS this would be unsafe - you should always ask the real time clock or tick counter how much time has elapsed each time because otherwise any errors accumulate so you will get less and less accurate over time. This is true even on a real time system because even if a real time system could sleep accurately for 1 second, it takes some time for your code to run so this timing error would accumulate on each pass through the loop.
In Windows for example, there is a possibility to create a waitable timer object.
If that's Your operating system check the documentation here for example Waitable Timer Objects.
From the code You presented it looks like what You are trying to do can be done much easier with sleep. It doesn't make sense to guarantee that Your loop body is executed exactly every 1 second. Instead make it execute 10 times a second and check if the time that elapsed form the last time, You took some action, is more than a second or not. If not, do nothing. If yes, take action (print Your message, increment variables etc), store the time of last action and loop again.
Sleep(1000);
http://msdn.microsoft.com/en-us/library/ms686298(VS.85).aspx