Related
I'm not sure if the title is right but...
I want to animate (with html + canvas + javascript) a section of a road with a given density/flow/speed configuration. For that, I need to have a "source" of vehicles in one end, and a "sink" in the other end. Then, a certain parameter would determine how many vehicles per time unit are created, and their (constant) speed. Then, I guess I should have a "clock" loop, to increment the position of the vehicles at a given frame-rate. Preferrably, a user could change some values in a form, and the running animation would update accordingly.
The end result should be a (much more sophisticated, hopefully) variation of this (sorry for the blinking):
Actually this is a very common problem, there are thousands of screen-savers that use this effect, most notably the "star field", which has parameters for star generation and star movement. So, I believe there must be some "design pattern", or more widespread form (maybe even a name) for this algoritm. What would solve my problem would be some example or tutorial on how to achieve this with common control flows (loops, counters, ifs).
Any idea is much appreciated!
I'm not sure of your question, this doesn't seem an algorithm question, more like programming advice. I have a game which needs exactly this (for monsters not cars), this is what I did. It is in a sort of .Net psuedocode but similar stuff exists in other environments.
If you are running an animation by hand, you essentially need a "game-loop".
while (noinput):
timenow = getsystemtime();
timedelta = timenow - timeprevious;
update_object_positions(timedelta);
draw_stuff_to_screen();
timeprevious = timenow;
noinput = check_for_input()
The update_object_positions(timedelta) moves everything along timedelta, which is how long since this loop last executed. It will run flat-out redrawing every timedelta. If you want it to run at a constant speed, say once every 20 mS, you can stick in a thread.sleep(20-timedelta) to pad out the time to 20mS.
Returning to your question. I had a car class that included its speed, lane, type etc as well as the time it appears. I had a finite number of "cars" so these were pre-generated. I held these in a list which I sorted by the time they appeared. Then in the update_object_position(time) routine, I saw if the next car had a start time before the current time, and if so I popped cars off the list until the first (next) car had a start time in the future.
You want (I guess) an infinite number of cars. This requires only a slight variation. Generate the first car for each lane, record its start time. When you call update_object_position(), if you start a car, find the next car for that lane and its time and make that the next car. If you have patterns that you want to repeat, generate the whole pattern in one go into a list, and then generate a new pattern when that list is emptied. This would also work well in terms of letting users specify variable pattern flows.
Finally, have you looked at what happens in real traffic flows as the volume mounts? Random small braking activities cause cars behind to slightly over-react, and as the slight over-reactions accumulate it turns into cars completely stopping a kilometre back up the road. Its quite strange, and so might be a great effect in your wallpaper/screensaver whatever as well as being a proper simulation.
I'd like to a counter to run in the background while my game is being played so that when the player survives for say 1 minute, something happens.
Currently, I'm thinking of doing this by getting the system time at start (say in surfaceCreated) and then in my physics update method, getting the current time and comparing the two. When 60,000 ms have passed then I know obviously 1 minute has passed.
Is this the best way to do this? Or is there another/better/simpler way.
Thanks all
That's a good way to go about it.
There's not many other options. In my game, I have a stopwatch that stops resets right before the frame update, so I can determine the amount of time spent doing other things. Then, each object is stepped with this amount of time.
It's good because it allows me to move each object at a speed relative to time rather than framerate, so if framerate differs on a different device, things still move at the same speed.
If you're not doing this, you really should be. If your step function looks something like
object.x += speed.x;
then it really should be
object.x += speed.x (in units/s) * step_time (in ms) / 1000.0
If you are doing this, it's probably best just to make a timer object that runs a Runnable when the timer expires (i.e it sums up the step-times and fires when it reaches 60sec).
tl;dr: I want to predict file copy completion. What are good methods given the start time and the current progress?
Firstly, I am aware that this is not at all a simple problem, and that predicting the future is difficult to do well. For context, I'm trying to predict the completion of a long file copy.
Current Approach:
At the moment, I'm using a fairly naive formula that I came up with myself: (ETC stands for Estimated Time of Completion)
ETC = currTime + elapsedTime * (totalSize - sizeDone) / sizeDone
This works on the assumption that the remaining files to be copied will do so at the average copy speed thus far, which may or may not be a realistic assumption (dealing with tape archives here).
PRO: The ETC will change gradually, and becomes more and more accurate as the process nears completion.
CON: It doesn't react well to unexpected events, like the file copy becoming stuck or speeding up quickly.
Another idea:
The next idea I had was to keep a record of the progress for the last n seconds (or minutes, given that these archives are supposed to take hours), and just do something like:
ETC = currTime + currAvg * (totalSize - sizeDone)
This is kind of the opposite of the first method in that:
PRO: If the speed changes quickly, the ETC will update quickly to reflect the current state of affairs.
CON: The ETC may jump around a lot if the speed is inconsistent.
Finally
I'm reminded of the control engineering subjects I did at uni, where the objective is essentially to try to get a system that reacts quickly to sudden changes, but isn't unstable and crazy.
With that said, the other option I could think of would be to calculate the average of both of the above, perhaps with some kind of weighting:
Weight the first method more if the copy has a fairly consistent long-term average speed, even if it jumps around a bit locally.
Weight the second method more if the copy speed is unpredictable, and is likely to do things like speed up/slow down for long periods, or stop altogether for long periods.
What I am really asking for is:
Any alternative approaches to the two I have given.
If and how you would combine several different methods to get a final prediction.
If you feel that the accuracy of prediction is important, the way to go about about building a predictive model is as follows:
collect some real-world measurements;
split them into three disjoint sets: training, validation and test;
come up with some predictive models (you already have two plus a mix) and fit them using the training set;
check predictive performance of the models on the validation set and pick the one that performs best;
use the test set to assess the out-of-sample prediction error of the chosen model.
I'd hazard a guess that a linear combination of your current model and the "average over the last n seconds" would perform pretty well for the problem at hand. The optimal weights for the linear combination can be fitted using linear regression (a one-liner in R).
An excellent resource for studying statistical learning methods is The Elements of
Statistical Learning by Hastie, Tibshirani and Friedman. I can't recommend that book highly enough.
Lastly, your second idea (average over the last n seconds) attempts to measure the instantaneous speed. A more robust technique for this might be to use the Kalman filter, whose purpose is exactly this:
Its purpose is to use measurements observed over time, containing
noise (random variations) and other inaccuracies, and produce values
that tend to be closer to the true values of the measurements and
their associated calculated values.
The principal advantage of using the Kalman filter rather than a fixed n-second sliding window is that it's adaptive: it will automatically use a longer averaging window when measurements jump around a lot than when they're stable.
Imho, bad implementations of ETC are wildly overused, which allows us to have a good laugh. Sometimes, it might be better to display facts instead of estimations, like:
5 of 10 files have been copied
10 of 200 MB have been copied
Or display facts and an estimation, and make clear that it is only an estimation. But I would not display only an estimation.
Every user knows that ETCs are often completely meaningless, and then it is hard to distinguish between meaningful ETCs and meaningless ETCs, especially for inexperienced users.
I have implemented two different solutions to address this problem:
The ETC for the current transfer at start time is based on a historic speed value. This value is refined after each transfer. During the transfer I compute a weighted average between the historic data and data from the current transfer, so that the closer to the end you are the more weight is given to actual data from the transfer.
Instead of showing a single ETC, show a range of time. The idea is to compute the ETC from the last 'n' seconds or minutes (like your second idea). I keep track of the best and worst case averages and compute a range of possible ETCs. This is kind of confusing to show in a GUI, but okay to show in a command line app.
There are two things to consider here:
the exact estimation
how to present it to the user
1. On estimation
Other than statistics approach, one simple way to have a good estimation of the current speed while erasing some noise or spikes is to take a weighted approach.
You already experimented with the sliding window, the idea here is to take a fairly large sliding window, but instead of a plain average, giving more weight to more recent measures, since they are more indicative of the evolution (a bit like a derivative).
Example: Suppose you have 10 previous windows (most recent x0, least recent x9), then you could compute the speed:
Speed = (10 * x0 + 9 * x1 + 8 * x2 + ... + x9) / (10 * window-time) / 55
When you have a good assessment of the likely speed, then you are close to get a good estimated time.
2. On presentation
The main thing to remember here is that you want a nice user experience, and not a scientific front.
Studies have demonstrated that users reacted very badly to slow-down and very positively to speed-up. Therefore, a good progress bar / estimated time should be conservative in the estimates presented (reserving time for a potential slow-down) at first.
A simple way to get that is to have a factor that is a percentage of the completion, that you use to tweak the estimated remaining time. For example:
real-completion = 0.4
presented-completion = real-completion * factor(real-completion)
Where factor is such that factor([0..1]) = [0..1], factor(x) <= x and factor(1) = 1. For example, the cubic function produces the nice speed-up toward the completion time. Other functions could use an exponential form 1 - e^x, etc...
My bike computer can show me various figures such as distance travelled, time elapsed, max speed, average speed, current speed etc. I usually have it set to display the current and average speeds.
You can reset the distance and time (both together) at any point; the max and average speeds are calculated since the last reset. The distance is taken from the wheel sensor (you have to calibrate it initially to tell it the circumference of your wheel) and the time is from its own real-time clock.
Now, quite often while I am cycling along, I will be going at well above the displayed average speed and yet the average speed shown will go down. As a concrete example, this evening I was cycling home and my current speed was holding steady at 19.5 mph; my average was showing 12.6 mph and as I looked at it, it clicked downwards to 12.5.
What I'm trying to work out is what kind of bizarre averaging algorithm it is using that can give this effect. I can't believe it's doing any kind of fancy stuff other than total distance / total time. I guess it must be some sort of rounding / boundary condition but I can't work out what. Any suggestions?
[I asked this around the office at work but nobody had any ideas other than that I should stop worrying about these sorts of details! Hey, I have to think about something when I'm cycling, it's 9 miles each way...]
I'm going to guess that it has a history of a certain number of data points and displays the average over them. As time goes on the older points are pushed off.
If you were going faster at the point far enough back to be the end of the history pushing off a point will lower your average.
It's not a running average, it's supposed to be the average for the whole trip, right? At least that's what I always assumed mine was doing.
I've noticed that effect too. My theory is that both the clock and the distance counter it uses for the average have a fairly low resolution, so sometimes the clock counter ticks up while the distance counter stays steady, and you get the dip. For Example:
dist time spd
8.5 40.1 12.72
8.5 40.2 12.69
If they are using an integer processor and fixed point, truncation would make the drop appear even larger
It's really a motivational technique.
It probably uses something similar to the Remaining time estimation algorithm.
It's timing between rotations of the wheel but it can easily miss a pass of the magnet over the sensor because of a bump in the road or noise.
So you measure a speed half the correct value for that one data point, it then does a running average so that bad point pollutes the speed for the next few revolutions.
The system needs to sample at some (probably constant) rate.
In order to compute a moving average it only stores at most N datapoints.
So in order to update the average it must drop one of its stored points to get a new average, and if the dropped point was faster than your current speed, the moving average would drop.
How can you make the display frames per second be independent from the game logic? That is so the game logic runs the same speed no matter how fast the video card can render.
I think the question reveals a bit of misunderstanding of how game engines should be designed. Which is perfectly ok, because they are damn complex things that are difficult to get right ;)
You are under the correct impression that you want what is called Frame Rate Independence. But this does not only refer to Rendering Frames.
A Frame in single threaded game engines is commonly referred to as a Tick. Every Tick you process input, process game logic, and render a frame based off of the results of the processing.
What you want to do is be able to process your game logic at any FPS (Frames Per Second) and have a deterministic result.
This becomes a problem in the following case:
Check input:
- Input is key: 'W' which means we move the player character forward 10 units:
playerPosition += 10;
Now since you are doing this every frame, if you are running at 30 FPS you will move 300 units per second.
But if you are instead running at 10 FPS, you will only move 100 units per second. And thus your game logic is not Frame Rate Independent.
Happily, to solve this problem and make your game play logic Frame Rate Independent is a rather simple task.
First, you need a timer which will count the time each frame takes to render. This number in terms of seconds (so 0.001 seconds to complete a Tick) is then multiplied by what ever it is that you want to be Frame Rate Independent. So in this case:
When holding 'W'
playerPosition += 10 * frameTimeDelta;
(Delta is a fancy word for "Change In Something")
So your player will move some fraction of 10 in a single Tick, and after a full second of Ticks, you will have moved the full 10 units.
However, this will fall down when it comes to properties where the rate of change also changes over time, for example an accelerating vehicle. This can be resolved by using a more advanced integrator, such as "Verlet".
Multithreaded Approach
If you are still interested in an answer to your question (since I didn't answer it but presented an alternative), here it is. Separating Game Logic and Rendering into different threads. It has it's draw backs though. Enough so that the vast majority of Game Engines remain single threaded.
That's not to say there is only ever one thread running in so called single threaded engines. But all significant tasks are usually in one central thread. Some things like Collision Detection may be multithreaded, but generally the Collision phase of a Tick blocks until all the threads have returned, and the engine is back to a single thread of execution.
Multithreading presents a whole, very large class of issues, even some performance ones since everything, even containers, must be thread safe. And Game Engines are very complex programs to begin with, so it is rarely worth the added complication of multithreading them.
Fixed Time Step Approach
Lastly, as another commenter noted, having a Fixed size time step, and controlling how often you "step" the game logic can also be a very effective way of handling this with many benefits.
Linked here for completeness, but the other commenter also links to it:
Fix Your Time Step
Koen Witters has a very detailed article about different game loop setups.
He covers:
FPS dependent on Constant Game Speed
Game Speed dependent on Variable FPS
Constant Game Speed with Maximum FPS
Constant Game Speed independent of Variable FPS
(These are the headings pulled from the article, in order of desirability.)
You could make your game loop look like:
int lastTime = GetCurrentTime();
while(1) {
// how long is it since we last updated?
int currentTime = GetCurrentTime();
int dt = currentTime - lastTime;
lastTime = currentTime;
// now do the game logic
Update(dt);
// and you can render
Draw();
}
Then you just have to write your Update() function to take into account the time differential; e.g., if you've got an object moving at some speed v, then update its position by v * dt every frame.
There was an excellent article on flipcode about this back in the day. I would like to dig it up and present it for you.
http://www.flipcode.com/archives/Main_Loop_with_Fixed_Time_Steps.shtml
It's a nicely thought out loop for running a game:
Single threaded
At a fixed game clock
With graphics as fast as possible using an interpolated clock
Well, at least that's what I think it is. :-) Too bad the discussion that pursued after this posting is harder to find. Perhaps the wayback machine can help there.
time0 = getTickCount();
do
{
time1 = getTickCount();
frameTime = 0;
int numLoops = 0;
while ((time1 - time0) TICK_TIME && numLoops < MAX_LOOPS)
{
GameTickRun();
time0 += TICK_TIME;
frameTime += TICK_TIME;
numLoops++;
// Could this be a good idea? We're not doing it, anyway.
// time1 = getTickCount();
}
IndependentTickRun(frameTime);
// If playing solo and game logic takes way too long, discard pending
time.
if (!bNetworkGame && (time1 - time0) TICK_TIME)
time0 = time1 - TICK_TIME;
if (canRender)
{
// Account for numLoops overflow causing percent 1.
float percentWithinTick = Min(1.f, float(time1 - time0)/TICK_TIME);
GameDrawWithInterpolation(percentWithinTick);
}
}
while (!bGameDone);
Enginuity has a slightly different, but interesting approach: the Task Pool.
Single-threaded solutions with time delays before displaying graphics are fine, but I think the progressive way is to run game logic in one thread, and displaying in other thread.
But you should synchronize threads right way ;) It'll take a long time to implement, so if your game is not too big, single-threaded solution will be fine.
Also, extracting GUI into separate thread seems to be great approach. Have you ever seen "Mission complete" pop-up message while units are moving around in RTS games? That's what I'm talking about :)
This doesn' cover the higher program abstraction stuff, i.e. state machines etc.
It's fine to control movement and acceleration by adjusting those with your frame time lapse.
But how about stuff like triggering a sound 2.55 seconds after this or that, or changing
game level 18.25 secs later, etc.
That can be tied up to an elapsed frame time accumulator (counter), BUT these timings can
get screwed up if your frame rate falls below your state script resolution
i.e if your higher logic needs 0.05 sec granularity and you fall below 20fps.
Determinism can be kept if the game logic is run on a separate "thread"
(at the software level, which I would prefer for this, or OS level) with a fixed time-slice, independent of fps.
The penalty might be that you might waste cpu time in-between frames if not much is happening,
but I think it's probably worth it.
From my experience (not much) Jesse and Adam's answers should put you on the right track.
If you are after further information and insight into how this works, i found that the sample applications for TrueVision 3D were very useful.