   correct usage of acceleration ( howto fix )
  [ This is based off of my code to my previous post about fixed-timestep physics.]My acceleration is somehow affected by my display framerate. I'm supposed to be using a fixed time-based integrator. And my physics fps is constant at 100fps ( regardless of display fps. )If I set display fps = 30, and physics fps = 100, it takes about 4 seconds for my ships acceleration to reach the max_vel(0.75). But if I uncap fps ( about 320fps ), it takes my ships acceleration only 1 second to reach max vel![1] Do you see where my problem is? The most likely functions are: Actor.update(), GameMain.update(), GameMain().adjusted_speed(), Actor.accelerate(), Actor.add_accel(), Ship().handle_input()[2] My GameMain.adjusted_speed() doesn't use dt. I'm not sure if it should? ( Even if it should, I think my .accel problem is somewhere else. )# game.py#!/usr/bin/python__author__ = "Jake b"VERSION = "0.6"WINDOW_TITLE = "fixed-timestep (euler): v%s [ %s ]" % (VERSION, __author__)try:import sysimport pygamefrom pygame.locals import *from pygame.sprite import RenderPlainimport randomfrom euclid import Vector2, Vector3from actor import Actor, Ship, Asteroidexcept ImportError, err:print "Couldn't load module. %s" % (err)sys.exit(2)class GameMain():"""game Main entry point. handles intialization of game and graphics.methods:update() : physics framerate logic, calls .integrate()integrate() : physicsmembers:dt : physics fixed-timestep ( defined as milliseconds )actor_sprites : RenderPlain() sprite group, holds all spritesplayer : player Ship() objectasteroids : Asteroid()s objects"""bDone = Falsedef __init__(self, width=800, height=600):"""Initialize PyGame"""pygame.init()self.width, self.height = width, heightself.screen = pygame.display.set_mode(( self.width, self.height ))pygame.display.set_caption( WINDOW_TITLE )self.dt = 10. #.01 # 10 milliseconds ( or 1/100th of sec )self.t = 0.self.timeCur = pygame.time.get_ticks()self.accumulator = 0.# sprite group, all Actors(), Ship()s, and Asteroid()s will join this:self.actor_sprites = RenderPlain()self.clock = pygame.time.Clock()self.fps = FPSText( self )# Actor() instancesself.player = Ship(self)# spawn asteroidsself.asteroids = []self.next_round()def adjusted_speed( self, speed_in_px_per_sec ):"""input: speed per seconds. output: speed per ms. """speed_in_px_per_ms =  speed_in_px_per_sec / 1000.#speed[ms] = speed[sec]/1000.return speed_in_px_per_msdef main_loop(self):"""Game() main loop"""while not self.bDone:self.handle_events()self.update()self.draw()# toggle: FPS cap = .fps_limit, or no cap to FPSif self.bLimitFPS: self.clock.tick( self.fps_limit )else: self.clock.tick()def integrate(self, dt):"""physics update, integrate."""self.actor_sprites.update( dt ) # update Actor()sdef update(self):"""integrate / update physics. using fixed-timestep.based off of: http://www.gaffer.org/game-physics/fix-your-timestep"""self.timeNew = pygame.time.get_ticks()self.timeDelta = self.timeNew - self.timeCurself.timeCur = self.timeNew# clamp timeDelta so it doesn't reach insanely high numbers if window# loses focus for extended period of time. capped at 250msif self.timeDelta > 250: self.timeDelta = 250self.accumulator += self.timeDeltawhile self.accumulator >= self.dt:self.integrate( self.dt ) # not sure why tut args are (t, dt) ?self.t += self.dtself.accumulator -= self.dtdef handle_events(self):"""do regular events. Also sends copies to Ship(), etc..."""# ...def draw(self):"""render screen"""# clear; render; update;self.screen.fill( pygame.color.Color("black") )self.actor_sprites.draw( self.screen )pygame.display.flip()def next_round(self):"""spawn asteroids for next_round."""# ...if __name__ == "__main__":# entry pointmain_window = GameMain()main_window.main_loop()# actor.py# actor.py__author__ = "Jake b"VERSION = "0.6"try:import randomfrom math import *import pygamefrom pygame.locals import *from euclid import Vector2except ImportError, err:print "Couldn't load module. %s" % (err)sys.exit(2)class Actor(pygame.sprite.Sprite):"""Base actor class. Handles physics, and rendering.methods:__init__(loc, vel, accel) : just initupdate(dt) : physicshandle_events(events) : main events loophandle_input() : handle key input not handled in .handle_events()accelerate(magnitude) :  accelerate along  normal_forewarddecelerate(magnitude) : accelerate along -normal_forewardnormal_foreward() : Vector2() : returns normal_forewardtruncate( Vector2, magnitude ) : Vector2() : truncates vector to magnitudespawn() : add to sprite groupkill() rem from sprite groupdraw() : [todo:] main render, derived from this_get_topleft_offset() : Rect() : get offset for rect.topleft based on loc_keep_onscreen() : keep on screen ( wrapping boundries )members:screen : actual screen root surfaceloc, vel, accel, max_vel, max_force: Vector2() self explainatory quanitiesrotation, mass, sprite_w, sprite_h = scalars"""def __init__( self, game, loc=Vector2(0.,0.), vel=Vector2(0.,0.),accel=Vector2(0.,0.), mass=1., sprite_w=15, sprite_h=15, color="blue" ):"""init loc, vel, accel."""pygame.sprite.Sprite.__init__(self)self.game = gameself.loc = locself.vel = velself.accel = accelself.mass = massself.rotation = radians(-90)self.max_vel = self.game.adjusted_speed( 1000 )self.max_force = self.game.adjusted_speed( 200 )self.sprite_w, self.sprite_h = sprite_w, sprite_h# placeholder: for now render a Rect() instead of a spriteself.image = pygame.Surface([sprite_w, sprite_h])self.image.fill( pygame.color.Color(color) )self.rect = self.image.get_rect()self.rect.topleft = self._get_topleft_offset()self.spawn() # add to sprite groupdef accelerate(self, magnitude):"""accelerate along foreward_normal"""accel = self.normal_foreward()accel *= magnitudeself.add_accel( accel )# old: self.accel += accel ( use function so it gets truncate()ed )def decelerate(self, magnitude):"""decelerate, (or: accelerate along -normal_foreward)"""self.accelerate( -magnitude )def add_accel(self, force):"""add a Vector2() force to the .accel Vector2()"""force = self.truncate( force, self.max_force )self.accel += force / self.massdef update(self, dt):"""update physics, dt = the fixed-timestepnote: sets self.accel = Vector2(0,0) after every .update()"""self.loc += self.vel * dtself.vel = self.truncate( self.vel + self.accel*dt, self.max_vel )# reset accel every physics update()self.accel = Vector2(0., 0.)# update .rect to with .locself._keep_onscreen()self.rect.topleft = self._get_topleft_offset()def truncate( self, vector, magnitude ):"""truncates Vector2()/Vector3() so that vector.magnitude() <= magnitude"""if vector.magnitude() > magnitude:vector.normalize()vector *= magnitudereturn vectordef normal_foreward(self):"""get the normal_foreward for this Actor()"""foreward = Vector2( cos( self.rotation ), sin( self.rotation ) )return foreward.normalize()def spawn(self):"""add Actor() to sprite group, move to proper location, etc..."""self.game.actor_sprites.add( self ) # add to sprite groupdef kill(self):"""kill player/asteroid/whatever"""pygame.sprite.Sprite.kill(self) # remove from sprite groupdef _keep_onscreen(self):"""keep self onscreen, wrapping on edges"""w,h = self.game.screen.get_size()if self.loc.x < 0: self.loc.x = wif self.loc.x > w: self.loc.x = 0if self.loc.y < 0: self.loc.y = hif self.loc.y > h: self.loc.y = 0def _get_topleft_offset(self):# loc is based on center of sprite, so subtract to get topleftx = self.loc.x - ( self.sprite_w / 2 )y = self.loc.y - ( self.sprite_h / 2 )return (x, y)class Ship(Actor):"""Ship() specific"""def __init__( self, game, loc=Vector2(0.,0.), vel=Vector2(0.,0.),accel=Vector2(0.,0.), mass=1., sprite_w=30, sprite_h=30, color="red" ):"""Overwrite size and other stuff."""Actor.__init__(self, game, loc, vel, accel, mass, sprite_w, sprite_h,color )self.max_vel = self.game.adjusted_speed( 750 )self.max_force = self.game.adjusted_speed( 200 )self.spawn()def spawn(self):"""spawn random loc, random vel, and random direction"""Actor.spawn(self)w,h = self.game.screen.get_size()self.loc = w/2, h/2self.vel = Vector2(0., 0.)self.accel = Vector2(0., 0.)def handle_input(self):"""derive to handle key input not handled by events"""keys = pygame.key.get_pressed()# reset accel# just incase .handle_input() is called more than once per each .update()# but this either doesn't help, or barely noticeably helps ( still 3sec error )self.accel = Vector2(0., 0.)# upif keys[K_UP]: self.accelerate( self.game.adjusted_speed( 1 ) )# downif keys[K_DOWN]: self.decelerate( self.game.adjusted_speed( 1 ) )class Asteroid(Actor):"""Asteroid specific"""# ...thanks,--monkey   
  How do I fix my code? Do you need more information? Or is it too much?The problem is that my Ship() accelerates at different speeds based on my FPS. If fps = 30, it takes 4 seconds to reach max acceleration. If fps = 320, it takes 1 second to reach max acceleration. (Both display framerates are tied to physics updates framerate 100fps )Here its stripped down as small as I think it can go:game.pyclass GameMain():def adjusted_speed( self, speed_in_px_per_sec ):"""input: speed per seconds. output: speed per ms.[ Used anywhere I set vel, or add accels. ]warning!: maybe the problem is I need to have self.dt in this functionsomehow ?? """speed_in_px_per_ms =  speed_in_px_per_sec / 1000.#speed[ms] = speed[sec]/1000.return speed_in_px_per_msdef update(self):"""integrate / update physics. using fixed-timestep.based off of: http://www.gaffer.org/game-physics/fix-your-timestep"""self.timeNew = pygame.time.get_ticks()self.timeDelta = self.timeNew - self.timeCurself.timeCur = self.timeNewif self.timeDelta > 250: self.timeDelta = 250self.accumulator += self.timeDeltawhile self.accumulator >= self.dt:self.integrate( self.dt ) # not sure why tut args are (t, dt) ?self.t += self.dtself.accumulator -= self.dtdef integrate(self, dt):"""physics update, integrate."""self.actor_sprites.update( dt ) # update Actor()sActor.pyclass Ship(Actor):"""Ship() specific"""def __init__( self ):self.max_vel = self.game.adjusted_speed( 750 )self.max_force = self.game.adjusted_speed( 200 )def handle_input(self):keys = pygame.key.get_pressed()# reset accel to prevent adding .add_accel() more than once per update()# just incase .handle_input() is called more than once per each .update()# but this does not fix my accel error.self.accel = Vector2(0., 0.)# upif keys[K_UP]: self.accelerate( self.game.adjusted_speed( 1 ) )class Actor(pygame.sprite.Sprite):def update(self, dt):"""update physics, dt = the fixed-timestepnote: sets self.accel = Vector2(0,0) after every .update()"""self.loc += self.vel * dtself.vel = self.truncate( self.vel + self.accel*dt, self.max_vel )# reset accel every physics update() because I .add_accel() every frame.self.accel = Vector2(0., 0.)def accelerate(self, magnitude):"""accelerate along foreward_normal"""accel = self.normal_foreward()accel *= magnitudeself.add_accel( accel )def add_accel(self, force):"""add a Vector2() force to the .accel Vector2()"""force = self.truncate( force, self.max_force )self.accel += force / self.massdef normal_foreward(self):"""get the normal_foreward for this Actor()"""foreward = Vector2( cos( self.rotation ), sin( self.rotation ) )return foreward.normalize()def truncate( self, vector, magnitude ):"""truncates Vector2()/Vector3() so that vector.magnitude() <= magnitude"""if vector.magnitude() > magnitude:vector.normalize()vector *= magnitudereturn vectorEdit: I *think* that my physics updates / fps is constant, but maybe i'm measuring wrongdef draw(self):"""draw display FPS and physics FPS"""self.text = "FPS: %d, physicsFPS: %d avg [ %d cur step ]" % (self.clock.get_fps(), self.game.physics_fps_avg, self.game.physics_fps )def update(self):"""update time"""# ... snip ...# physicsFPS, calc. fps and fps_avg for physics update framerateif self.timeNew - self.physics_timeLast >= 1000.:self.physics_timeLast = self.timeNewself.physics_fps_avg += self.physics_fpsself.physics_fps_avg /= 2self.physics_fps = 0.while self.accumulator >= self.dt:self.integrate( self.dt )self.t += self.dtself.accumulator -= self.dtself.physics_fps += 1 # physicsFPS# ... snip ...;  You know I was getting weird FPS in my game, and from what you described sounds like your rendering, or updating your scene depending on how many FPS your system can handle.  By all means this is a method, but what if your FPS isn't at a constant rate?  You'll get the problem that is occurring right now.Do you have some kind of antivirus program on your system ?If so try turning that off, and killing other high resource programs and see if that doesn't change it.If at all you could always just have a max acceleration that you get after something is achieved, and until that achievement have a constant speed like your max speed except maybe half the speed, and just keep that in an update managed by a boolean value.maybe likebool max_speed;bool IsRunning;int speed = 5;int max_speed = 10;while(IsRunning){  if(max_speed) ship_speed = max_speed;  else ship_speed = speed;}That is how I would fix your problem.   That way your speed of the ship has nothing to do with how many FPS your system is able to push out, or will be one speed over another one second or later, but at a constant speed unless certain achievements are meet.Good Luck ;)   ;Quote:Original post by aleisterbukowskiYou know I was getting weird FPS in my game, and from what you described sounds like your rendering, or updating your scene depending on how many FPS your system can handle.  By all means this is a method, but what if your FPS isn't at a constant rate?  You'll get the problem that is occurring right now.My video and physics framerates should be properly decoupled, so regardless of the video FPS, the physics updates at the same speed. But, they are not disconnected properly, or i'm doing .update() incorrectly, or i'm doing .accelerate() incorrectly?Quote:Original post by aleisterbukowskiDo you have some kind of antivirus program on your system ? If so try turning that off, and killing other high resource programs and see if that doesn't change it. I disabled Antivirus, and checked the process manager for any thing else. Turning  everything off I can, it didn't fix the acceleration problem.Quote:Original post by aleisterbukowskiIf at all you could always just have a max acceleration that you get after something is achieved, and until that achievement have a constant speed like your max speed except maybe half the speed, and just keep that in an update managed by a boolean value.maybe like*** Source Snippet Removed ***That is how I would fix your problem.   That way your speed of the ship has nothing to do with how many FPS your system is able to push out, or will be one speed over another one second or later, but at a constant speed unless certain achievements are meet.I really need to solve this problem. I can't work on other physics demos until I get this basic [particle kinematics?] working correctly.I thought that this would be a easy problem for most of the users in this forum because they solve problems a lot more complicated than this. Or am I missing something that makes it harder?To make it easier to look at, here's the file for download.fixed-timestep_acceleration_broke.zip;  Well, I appreciate your urgency and frustration, but you're basically asking people to debug your program from a listing. I don't even do that with my own programs, I use an interactive debugger.Ok, you're talking about a fixed timestep to your physics update. It takes an exact number of iterations to hit that max speed. How many iterations is that? How long did that take down to the tenth, if not hundredth, of a second? Chances are it's either getting there either 3.2 or 6.4 times as fast indicating your doing either a minimum of one or two updates per frame rather than a minimum of zero. With 30 fps you are mostly going to do 2-4 updates per frame. Some other program hogs the cpu you might shoot as high as 10 or even higher updates of a single frame. At 320 fps you should be doing one UPDATE per 2-4 frames.   ;  (1) Do commercial games use what I'm trying to achieve? Meaning does their physics updates always occur at the same frequency, regardless of the video FPS which can spike? Or am I assuming wrong, and they instead just target a static video FPS ?Quote:Original post by LilBudyWizerWell, I appreciate your urgency and frustration, but you're basically asking people to debug your program from a listing. I don't even do that with my own programs, I use an interactive debugger.Ok, you're talking about a fixed timestep to your physics update. It takes an exact number of iterations to hit that max speed. How many iterations is that? How long did that take down to the tenth, if not hundredth, of a second? Chances areI took stats of how long it took to accelerate to full speed on each of the framerate options: 30fps, 60fps, unlimited fps.I found that at 30fps and 60fps it always takes 75 iterations to hit max speed. The time to reach max accel was in the range: 1.22 secs to 1.226 secs . Running at 120fps the iterations would vary, from 90-92 at .747 secs to .776 secs.Running at variable / unlimited fps the iterations would vary from 158-164 at .743 secs to .823 secs.== running at 60fps ==[test1]   time: 1220 ms [ 1.220000 secs ]   iters: physics ( 75 ) frames ( 348 )   avg fps: physics ( 61.475410 ) avg fps: frames ( 285.245902 )[test2]   time: 1226 ms [ 1.226000 secs ]   iters: physics ( 75 ) frames ( 698 )   avg fps: physics ( 61.174551 ) frames ( 569.331158 )[test3]   time: 1225 ms [ 1.225000 secs ]   iters: physics ( 75 ) frames ( 975 )   avg fps: physics ( 61.224490 ) frames ( 795.918367 )== running at 30fps ==[test1]   time: 2535 ms [ 2.535000 secs ]   iters: physics ( 75 ) frames ( 1598 )   avg fps: physics ( 29.585799 ) frames ( 630.374753 )[test2]   time: 2523 ms [ 2.523000 secs ]   iters: physics ( 75 ) frames ( 2178 )   avg fps: physics ( 29.726516 ) frames ( 863.258026 )[test3]   time: 2535 ms [ 2.535000 secs ]   iters: physics ( 75 ) frames ( 2530 )   avg fps: physics ( 29.585799 ) frames ( 998.027613 )== running at max speed (jumps from 180ish to 220ish) ==[test1]   time: 756 ms [ 0.756000 secs ]   iters: physics ( 159 ) frames ( 535 )   avg fps: physics ( 210.317460 ) frames ( 707.671958 )[test2]   time: 745 ms [ 0.745000 secs ]   iters: physics ( 148 ) frames ( 677 )   avg fps: physics ( 198.657718 ) frames ( 908.724832 )[test3]   time: 745 ms [ 0.745000 secs ]   iters: physics ( 153 ) frames ( 885 )   avg fps: physics ( 205.369128 ) frames ( 1187.919463 )Quote:it's either getting there either 3.2 or 6.4 times as fast indicating your doing either a minimum of one or two updates per frame rather than a minimum of zero. With 30 fps you are mostly going to do 2-4 updates per frame. Some other program hogs the cpu you might shoot as high as 10 or even higher updates of a single frame. At 320 fps you should be doing one UPDATE per 2-4 frames.;  If your execution time for 75 iterations varies depending on the display framerate, then obviously the problem is that you're not updating your physics at a constant 100fps like you think you are. Your numbers don't really make much sense... Your data looks like you're changing the physics rate to 30fps or 60fps, not the display, but what you're saying is the opposite.And yes, many commercial game engines including Source use fixed time step for physics.   ;  Let's take a simple example. Let's say it was just an object moving in a straight line at a fixed speed, say 60 mph. That's 88 feet per second. If your timestep was 0.01s then that's 0.88 feet per timestep. Each update you move the object 0.88 feet in it's direction of travel. How many times you call it determines how far the object moves.What's it's speed? 60 mph. It has nothing to do with the frequency with which you call the routine. Each call updates the position for 0.01s. It doesn't matter whether you do 10, 100 or 1000 calls a second. The only differance the rate of the calls make is the scale of the game time. 10 calls a second means 1s of clock time is 0.1s of game time. Similarly 100 means 1s is 1s and for 1000 1s is 10s.How fast is the object moving on the screen? That depends upon your scales. One is the scale of the feet to pixels and the other is game time to clock time. Say it's 100 pixels per mile for the linear scale. So if the object is moving 60 mph it will move 100 pixels per minute. That minute is game time. If game time is moving 10 times faster than the clock then it's going to move 1000 pixels per minute by the clock. The object is moving at 60 mph irregardless of how fast it's moving across the screen.That's because you set it to move at 60 mph. Each call advances the game clock by 0.01s and moves the object by 0.88 ft. It's no differant than a map. Two geographical positions are a certain distance apart irregardless of the scale the map is drawn at. The scale of the map just determines how you convert distances on the map to distances in the real world.Assuming all your input is the same then the number of calls determines the positions of the objects. If 100 iterations doesn't produce the same positions irregardless of the rate of the calls then you're mixing up your times. You're getting clock time mixed up with game time. The game time is only advanced by the update. It is advanced by a fixed amount per update, i.e. the fixed timestep. The game loop determines how many times the update is called based upon the elapsed clock time and the time scale. If the last pass took 0.1s, your timestep is 0.01s and your time scale is 1:1 then you need to call update ten times this pass.As a generaly rule you need some type catch up. If you can't complete 100 updates per second then attempting to will just mean your frame rate gets slower and slower. So you might have an alternative update that can do 0.1s timesteps instead of 0.01s. Not as accurate, but better to lose accuracy than to drop to one frame every five minutes.   