2d trajectory planning of a spaceship with physics

后端 未结 6 1061
逝去的感伤
逝去的感伤 2020-12-23 18:19

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 an

6条回答
  •  执笔经年
    2020-12-23 18:41

    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 controlling 
    Variable Parameters:
      ImpulseAngle     = direction of impulse
      ImpulseThrust    = force of thrust
    Formula:
      Vx[new] = (cos(ImpulseAngle) * ImpulseThrust) + ExternalForceX  + (MassOfShip * Vx[current])
      Vy[new] = (sin(ImpulseAngle) * ImpulseThrust) + ExternalForceY  + (MassOfShip * Vy[current])
    

    Note that the above model assumes a constant External force (constant both in terms of its strength and direction); that is: akin to that of a gravitational field relatively distant from the area displayed (just like say the Earth gravity, considered within the span of a football field). If the scale of the displayed area is big relative to the source(s) of external forces, the middle term of the formulas above should then be modified to include: a trigonometric factor based on the angle between the center of the source and the current position and/or a [reversely] proportional factor based on the distance between the center of the source and the current position.
    Similarly, the Ship's mass is assumed to remain constant, it could well be a variable, based say on the mass of the Ship when empty, to which the weight of fuel is removed/added as the game progresses.

    Now... All the above assume that the dynamics of the system are controlled by the game designer: essentially choosing a set of values for the parameter mentioned and possibly adding a bit of complexity in the math of the formula (and also ensuring proper scaling to generally "keep" the ship within the display area).

    What if instead, the system dynamics were readily programmed into the game (and assumed to be hidden/random), and the task at hand is to write a program which will progressively decide the direction and thrust value of the impulses to drive the ship to its targeted destination, in a way that its velocity at the target be as close as possible to getTargetVelocity()? This is the "Problem A".

    This type of problem can be tackled with a PID Controller. In a nuthell, such a controller "decides" which amount of action (in this game's case = which impulse angle and amount of thrust to apply), based on three, weighed, factors, loosely defined below:

    • how far-off we are the current values from "set point": this is the P=Proportional part of PID
    • how fast are we approaching the "set point": this is the D=Derivative part of PID
    • how long and how much have we been away from the "set point": this is the I=Intergral part of PID

    A less sophisticated controller could for example only use the proportional factor. This would result in oscillating, sometimes with much amplitude on either side of the set point ("I'm X units away from where I'm supposed to be: let me yank the steering wheel and press on gas"). Such overshooting of the set point are tempered by the Derivative factor ("Yeah, I'm still not where I'm supposed to be but the progress I made since the last time I check is very big: better slow down a bit"). Finally the Integral part takes into account the fact that all things being equal with regards to the combined Proportional and Derivative part, a smaller or bigger action would be appropriate depending on whether we've been "off-track" for a long time or not and of much off track we've been all this time (eg. "Lately we've been tracking rather close to where we're supposed to be, no point in making rash moves")

    We can discuss the details implementing PID controllers for the specific needs of the space ship game, if that is effectively what is required. The idea was to provide a flavor of what can be done.

提交回复
热议问题