Alex Rivera | Logout

2d trajectory planning of a spaceship with physics

Asked 2010-04-01T13:52:11.830
13

I'm implementing a 2D game with ships in space.

In order to do it, I'm using LÖVE, which wraps Box2D with Lua. But I believe that my question can be answered by anyone with a greater understanding of physics than myself - so pseudo code is accepted as a response.

My problem is that I don't know how to move my spaceships properly on a 2D physics-enabled world. More concretely:

A ship of mass m is located at an initial position {x, y}. It has an initial velocity vector of {vx, vy} (can be {0,0}).

The objective is a point in {xo,yo}. The ship has to reach the objective having a velocity of {vxo, vyo} (or near it), following the shortest trajectory.

There's a function called update(dt) that is called frequently (i.e. 30 times per second). On this function, the ship can modify its position and trajectory, by applying "impulses" to itself. The magnitude of the impulses is binary: you can either apply it in a given direction, or not to apply it at all). In code, it looks like this:

function Ship:update(dt)
  m = self:getMass()
  x,y = self:getPosition()
  vx,vy = self:getLinearVelocity()
  xo,yo = self:getTargetPosition()
  vxo,vyo = self:getTargetVelocity()
  thrust = self:getThrust()

  if(???)
    angle = ???
    self:applyImpulse(math.sin(angle)*thrust, math.cos(angle)*thrust))
  end
end

The first ??? is there to indicate that in some occasions (I guess) it would be better to "not to impulse" and leave the ship "drift". The second ??? part consists on how to calculate the impulse angle on a given dt.

We are in space, so we can ignore things like air friction.

Although it would be very nice, I'm not looking for someone to code this for me; I put the code there so my problem is clearly understood.

What I need is an strategy - a way of attacking this. I kno

Edit
Report

3 Answers

4

In the absence of additional info, we can assume there are 3 forces acting upon the spaceship and eventually dictating its trajectory:

  • "impulses" : [user/program-controlled] force.
    The user (or program) appear to have full control over this, i.e. it controls the direction of the impulse and its thrust (probably within a 0-to-max range)
  • some external force: call it gravity, whatever...
    Such force could be driven by several sources but we're just interested in the resulting combined force: at a given time and space this external force acts upon the ship with a given strengh and direction. The user/program has no control over these.
  • inertia: this is related to the ship's current velocity and direction. This force generally causes the ship to continue in its current direction at its current speed. There may be other [space-age] parameters controlling the inertia but generally, it is proportional to both velocity and to the ship's mass (Intuitively, it will be easier to bring a ship to a stop if its current velocity is smaller and/or if its mass is smaller)

Apparently the user/program only controls (within limits) the first force.
It is unclear, from the question, whether the problem at hand is:

  • [Problem A] to write a program which discovers the dynamics of the system (and/or adapts to changes these dynamics).
    or..
  • [Problem B] to suggest a model -a formula- which can be used to compute the combined force eventually applied to the ship: the "weighed" sum of the user-controlled impulse and the other two system/physics-driven forces.

The latter question, Problem B, is more readily and succinctly explained, so let's suggest the following model:

Constant Parameters:
  ExternalForceX   = strength of the external force in the X direction
  ExternalForceY   = id. Y direction
  MassOfShip       = coeficient c
answered 2010-04-01T16:15:14.890
1

To just get from the current position to the destination with an initial velocity, then apply thrust along the normalized difference between the shortest path and the current velocity. You don't actually need the angle.

-- shortest path minus initial velocity
dx,dy = x0 - x - vx, y0 - y - vy

-- normalize the direction vector
magnitude = sqrt(dx*dx + dy*dy)
dx,dy = dx/magnitude, dy/mangitude

-- apply the thrust in the direction we just calculated
self:applyImpulse(thrust*dx, thrust*dy)

Note that this does not take the target velocity into account because that gets extremely complicated.

I have a very small Lua module for handling 2D vectors in this paste bin. You are welcome to use it. The code above would reduce to:

d = destination - position - velocity
d:normalize()
d = d * thrust
self:applyImpulse(d.x, d.y)
answered 2010-04-01T14:24:57.143
0

Are you expelling fuel? Your mass will change with time if you are.

Thrust is a reactive force. It's the rate of change of mass, times the speed of the exhaust relative to the spaceship.

Do you have external forces? If you do, these need to enter into your impulse calculation.

Let's assume a magical thrust with no mass being expelled, and no external forces.

Impulse has units of momentum. It's the integral of a force over time.

First off, you'll need to figure out exactly what the API calls "thrust" and impulse. If you're feeding it a thrust multiplied by a scalar (number), then applyImpulse has to do something else to your input to be able to use it as an impulse, because the units don't match up.

Assuming your "thrust" is a force, then you multiply that thrust by the time interval (1/30 second) to get the impulse, and break out the components.

Don't know if I'm answering your question, but hopefully that helps you to understand the physics a bit.

answered 2010-04-01T14:40:42.493

Your Answer