# PyBox2D car moves uncontrollably

I am trying to program TopDown Car using python and Box2D (similar to this tutorial: http://www.iforce2d.net/b2dtut/top-down-car ) The steering is so far limited to thres states of wheel rotation, that I will need to solve later, now I have problem with controlling the car velocity.

The problem is that the vehicle moves rather uncontrollably, I press "W" to move forward, "A" or "D" to steer, but then I ofttimes need to press "S" key to keep going in forward direction (which is of course counter-intuitive).

EDIT: I tried to convert world/object coordinates, it helped partially because now my car is moving from the beginning in straight line (it was always going slightly obliquely to the right, but now it has problems with turning, it turns uncontrollably and there is still the problem with messed-up directions (when I need the car to go forward after turning i have to press S

This is the main game loop: it should be updating PyGame frame 60 times per second, in Every frame I am cancelling lateral velocity of a body and then I am trying to controll the body

while running:
# Check the event queue
screen.fill((255, 255, 255,0))
for body in world.bodies:
for fixture in body.fixtures:
fixture.shape.draw(body, fixture)

# Cancelling lateral velocity
for wheel in Wheels:

if wheel in range(2):
continue # Rear wheels are not powered
else:
Current_Normal = wheel.GetWorldVector((0,1))
Current_N_Squared =  b2Dot(Current_Normal, wheel.linearVelocity) * Current_Normal

Right_Normal = wheel.GetWorldVector((1,0))
Right_Normal_Squared = b2Dot(Right_Normal, wheel.linearVelocity) * Right_Normal

Impulse = -Right_Normal_Squared * wheel.mass
if Impulse.length >max_lateral_impulse:
Impulse *= max_lateral_impulse/Impulse.length

wheel.ApplyLinearImpulse(Impulse, wheel.worldCenter, True)

# Allowing skidding

aimp = 0.05 * wheel.inertia * -wheel.angularVelocity
wheel.ApplyAngularImpulse(aimp, True)

current_forward_speed = Current_N_Squared.Normalize()

drag_force_magnitude = -2 * current_forward_speed
wheel.ApplyForce(drag_force_magnitude * Current_N_Squared,
wheel.worldCenter, True)

# Moving forward/backward
if event.type == KEYDOWN and event.key == K_w:
Left_Wheel.ApplyLinearImpulse(impulse=Left_Wheel.GetWorldVector((0, 10)), point =Left_Wheel.GetWorldVector((Left_Wheel.position)),wake = True)
Right_Wheel.ApplyLinearImpulse(impulse=Right_Wheel.GetWorldVector((0, 10)),point = Right_Wheel.GetWorldVector((Right_Wheel.position)),wake = True)

elif event.type == KEYDOWN and event.key == K_s:
Left_Wheel.ApplyLinearImpulse(impulse=Left_Wheel.GetWorldVector((0, -10)), point =Left_Wheel.GetWorldVector((Left_Wheel.position)),wake = True)
Right_Wheel.ApplyLinearImpulse(impulse=Right_Wheel.GetWorldVector((0, -10)),point = Right_Wheel.GetWorldVector((Right_Wheel.position)),wake = True)


If you want to play with my code in order to better see where the problem is I can give you the whole script (270 lines in total)

I know that to move more realistically I need to play with the aimp or max_lateral_velocity values. But first I need the car to be controlled better

EDIT 2: I am sorry, I was probably able to solve this problem by applying this:

Left_Wheel.ApplyLinearImpulse(b2Vec2(Left_Wheel.GetWorldVector((0, 10))), Left_Wheel.position,True)
Right_Wheel.ApplyLinearImpulse(b2Vec2(Right_Wheel.GetWorldVector((0, 10))), Right_Wheel.position,True)


This seems to be working, many thanks to Aleš Koblížek for patience Now my problem seems to be solved

The KEYDOWN event is fired every time the key is pressed down, so the impulse is applied only then. Instead, you should remember the state of the key and apply force in every iteration of the main loop if the key is pressed down.