Booster theory

Development areas for Allegiance core (IGC) design.
Spunkmeyer
Posts: 2013
Joined: Fri Jun 27, 2003 7:00 am
Location: Contact me regarding: CC, Slayer and AllegWiki.

Post by Spunkmeyer »

phoenix1 wrote:QUOTE (phoenix1 @ Mar 19 2013, 02:20 AM) How is the current speed of a ship calculated?
By measuring the impact pressure of dark matter.

Since you have necroed it for god knows what reason.... Trivia question: Does anyone know the reasoning behind:

top speed = ShipMaxSpeed * (1 + maxThrust / ShipMaxThrust)


Want bigger games? Log on to play at the official game time: 9pmET/8pmCT/7pmMT/6pmPT every day of the week. Also Saturdays 8pm UTC.

zombywoof
Posts: 6522
Joined: Mon Jul 14, 2008 4:59 am
Location: Over the Rainbow

Post by zombywoof »

I've necroed this post because I wanted information kept here, and then discovered I wanted more information than was here in the first place.
Image
Don't find fault, find a remedy; anybody can complain.
Cookie Monster wrote:QUOTE (Cookie Monster @ Apr 1 2009, 09:35 PM) But I don't read the forums I only post.
TurkeyXIII
Posts: 1460
Joined: Thu Dec 06, 2007 3:18 am
Location: Melbourne, Aus

Post by TurkeyXIII »

Linear drag.

There's a drag force on the ship equal to something like Fd = - v * (ShipMaxThrust / ShipMaxSpeed). Thus when v = max speed, the drag force is equal and opposite the max thrust, and full throttle only maintains current speed. When using a booster, the drag coefficient doesn't change but the amount of available thrust does, so v can get to ( ShipMaxSpeed * (1 + maxThrust / ShipMaxThrust) ) before the drag completely counters the thrust from both booster and ship. (Homework: Prove this result yourself!)

p1 I'm not entirely sure what you're asking. You can rearrange Newton's second law to get a kind of

dv = ( (CurrentThrust - v * (ShipMaxThrust / ShipMaxSpeed)) / mass ) dt

which solved for v is

v(t) = (CurrentThrust/ShipMaxThrust) * ShipMaxSpeed * ( 1 - e^(- ShipMaxThrust / (ShipMass * ShipMaxSpeed) * t) ) * (1 - (startingSpeed / ShipMaxSpeed)) + startingSpeed

or thereabouts.
QUOTE (Randall Munroe)14.2: Turkey consumption rate of the average American in milligrams per minute[/quote]
Image
zombywoof
Posts: 6522
Joined: Mon Jul 14, 2008 4:59 am
Location: Over the Rainbow

Post by zombywoof »

What's "currentthrust" then, what hte booster's giving? Let me see if that's correct.

Edit: I get V(t) = (boosterThrust * t)/(mass + (shipThrust * t)/(maxSpeed)) + startingSpeed

This matches the experimental values I got here:

https://docs.google.com/spreadsheet/ccc ... 0VFE#gid=0

Maximum V when t goes to infinity would be (boosterThrust * maxSpeed / shipThrust) + startingSpeed

or ShipMaxSpeed * (1 + maxThrust / ShipMaxThrust)

THANK YOU SO MUCH TURKEY YOU HAVE HELPED COR BALANCE EVERYWHERE!

The missing piece was that we have linear drag.


EDIT: Check that, I'm close but I'm not quite there. Can you find my mathemagical error? When I put t=10 into the equation I get V = 187 and change when experimental results should give me 210-220 range.

EDIT: Modifying it to 1/2 ship's max thrust seems to work perfectly. I have no idea why.
Last edited by zombywoof on Wed Mar 20, 2013 8:33 am, edited 1 time in total.
Image
Don't find fault, find a remedy; anybody can complain.
Cookie Monster wrote:QUOTE (Cookie Monster @ Apr 1 2009, 09:35 PM) But I don't read the forums I only post.
KGJV
Posts: 1474
Joined: Tue Jul 01, 2003 7:00 am
Location: Transilvania

Post by KGJV »

ship movements are computed in CshipIGC::ExecuteShipMove() in file igc/shipIGC.cpp line 2362.

you'll find all the math you need (and more!) in there (it's basically the drag stuff TurkeyXIII explained).

nb: don't forget that some ship properties are modified by GAs. For instance m_myHullType.GetThrust() is ship thrust ("max thrust" in ICE) * ship accel GA.
GAs are defined by faction at start of game then modified by some research.

i've copied (and cleaned a bit) the whole function here (big wall of code incoming, brace for impact):

Code: Select all

void    CshipIGC::ExecuteShipMove(Time          timeStart,
                                  Time          timeStop,
                                  Vector*       pVelocity,
                                  Orientation*  pOrientation)
{
    if (timeStop > timeStart)
    {
        //Adjust ship's heading, velocity, etc. based on its control settings.
        float   dT = timeStop - timeStart;
        assert (dT > 0.0f);

        float   thrust = m_myHullType.GetThrust();
        float   thrust2 = thrust * thrust;

        //Conversion factor ... Newtons to deltaV
        assert (GetMass() > 0.0f);
        float   thrustToVelocity = dT / GetMass();

    //No maneuvering if ripcording
        if (!m_pmodelRipcord)
        {
            //constrain the desired yaw/pitch/roll rates to an sphere rather than a box
                float   l = m_controls.jsValues[c_axisYaw]   * m_controls.jsValues[c_axisYaw] +
                        m_controls.jsValues[c_axisPitch] * m_controls.jsValues[c_axisPitch] +
                        m_controls.jsValues[c_axisRoll]  * m_controls.jsValues[c_axisRoll];

            if (l > 1.0f)
                l = 1.0f / sqrt(l);
            else
                l = 1.0f;

            float   tm = GetTorqueMultiplier() * thrustToVelocity;
            for (int i = 0; (i < 3); i++)
            {
                float   desiredRate = m_controls.jsValues[i] * l * m_myHullType.GetMaxTurnRate(i);
                float   maxDelta = tm * m_myHullType.GetTurnTorque(i);

                if (desiredRate < m_turnRates[i] - maxDelta)
                    m_turnRates[i] -= maxDelta;
                else if (desiredRate > m_turnRates[i] + maxDelta)
                    m_turnRates[i] += maxDelta;
                else
                    m_turnRates[i] = desiredRate;
            }
        }

        pOrientation->Yaw(   m_turnRates[c_axisYaw] * dT);
        pOrientation->Pitch(-m_turnRates[c_axisPitch] * dT);
        pOrientation->Roll(  m_turnRates[c_axisRoll] * dT);

        // Re-normalize the orientation matrix
        pOrientation->Renormalize();

        const Vector&   myBackward = pOrientation->GetBackward();

        float   speed = pVelocity->Length();
        float   maxSpeed = m_myHullType.GetMaxSpeed();

        assert (maxSpeed > 0.0f);

        //What would our velocity be if we simply let drag slow us down
        Vector  drag;
        {
            // double   f = exp(-thrust * thrustToVelocity / maxSpeed);
            double   f = exp(double(double(-thrust) * double(thrustToVelocity) / (double)maxSpeed));  // mmf type cast changes

            //New velocity = old velocity * f
            //drag = thrust required to create this change in velocity
            drag = *pVelocity * float((1.0 - f) / double(thrustToVelocity));
        }

        m_engineVector.x = m_engineVector.y = m_engineVector.z = 0.0f;    //Zero out the thrust

        bool    afterF = (m_stateM & afterburnerButtonIGC) != 0;
        float   thrustRatio = 0.0f;
        {
            IafterburnerIGC*    afterburner = (IafterburnerIGC*)(m_mountedOthers[ET_Afterburner]);

            if (afterburner)
            {
                float   abThrust = afterburner->GetMaxThrustWithGA(); //TheRock 15-8-2009
                if (afterF) {
                    thrustRatio = abThrust / thrust;
                }
                afterburner->IncrementalUpdate(timeStart, timeStop, false);

                float power = afterburner->GetPower();
                if (power != 0.0f)
                {
                    //Factor the afterburner thrust into drag (so that it will factor into the engine thrust)
                    drag += (power * abThrust) * myBackward;
                }
            }
        }

        //no maneuvering while ripcording
        if (!m_pmodelRipcord)
        {
            Vector  localThrust;
            if (m_stateM & (leftButtonIGC | rightButtonIGC |
                            upButtonIGC | downButtonIGC |
                            forwardButtonIGC | backwardButtonIGC))
            {
                //Under manual control: find out which direction to thrust in
                //get the throttle setting, but ramp between 0.2 and 1.0 (instead of 0.0 & 1.0)
                int   x = ((m_stateM & leftButtonIGC)     ? -1 : 0) + ((m_stateM & rightButtonIGC)   ?  1 : 0);
                int   y = ((m_stateM & downButtonIGC)     ? -1 : 0) + ((m_stateM & upButtonIGC)      ?  1 : 0);
                int   z = ((m_stateM & backwardButtonIGC) ?  1 : 0) + ((m_stateM & forwardButtonIGC) ? -1 : 0);

                if (x || y || z)
                {
                    //thrusting in at least one direction
                    localThrust.x = (thrust * (float)x);
                    localThrust.y = (thrust * (float)y);
                    localThrust.z = (thrust * (float)z);
                }
                else
                    localThrust = Vector::GetZero();
            }
            else
            {
                if ((m_stateM & coastButtonIGC) && !afterF)
                    localThrust = pOrientation->TimesInverse(drag);
                else
                {
                    float   negDesiredSpeed;
                    if (afterF)
                        negDesiredSpeed = maxSpeed * (-1.0f - thrustRatio);
                    else
                        negDesiredSpeed = (-0.5f * (1.0f + m_controls.jsValues[c_axisThrottle])) *
                                          ((speed > maxSpeed) ? speed : maxSpeed);

                    Vector  desiredVelocity = myBackward * negDesiredSpeed;

                    //Find out how much thrust is required to obtain our desired velocity,
                    //accounting for drag
                    // mmf added zero check and debugf
                    if (thrustToVelocity == 0.0f) debugf("shipIGC.cpp ~2394 thrustToVelocity = 0 about to devide by zero\n");
                    localThrust = pOrientation->TimesInverse((desiredVelocity - *pVelocity) / thrustToVelocity + drag);
                }
            }

            {
                //Clip the engine vector the the available thrust from the engine
                float   sm = m_myHullType.GetSideMultiplier();
                // mmf added zero checks and debugf
                if (sm == 0.0f) debugf("shipIGC.cpp ~2403 sm = 0 about to devide by zero\n");
                if ((m_myHullType.GetBackMultiplier()==0.0f)&&(localThrust.z<=0.0f))
                    debugf("shipIGC.cpp ~2405 backmultip = 0 about to devide by zero\n");
                Vector  scaledThrust(localThrust.x / sm,
                                     localThrust.y / sm,
                                     localThrust.z <= 0.0f ? localThrust.z : (localThrust.z / m_myHullType.GetBackMultiplier()));

                float   r2 = scaledThrust.LengthSquared();

                if (r2 == 0.0f)
                    m_engineVector = Vector::GetZero();
                else if (r2 <= thrust2)
                {
                    //No clipping of engine thrust required
                    m_engineVector = localThrust * *pOrientation;
                }
                else
                {
                    //Trying to thrust too much ... clip it back.
                    m_engineVector = (localThrust * *pOrientation) * (thrust / (float)sqrt(r2));
                }
            }
        }


        *pVelocity += thrustToVelocity * (m_engineVector - drag);

    }
}
Image
zombywoof
Posts: 6522
Joined: Mon Jul 14, 2008 4:59 am
Location: Over the Rainbow

Post by zombywoof »

Ok, so ignoring the vectors (because I'm only interested in boosting in one direction):

e^(-thrust*thrustToVelocity/maxSpeed)


drag =
drag = V * (1-(e^(((-thrust)*(thrustToVelocity)/maxSpeed))))/(dT/getMass)

also drag += (power*abThrust) *myBackward which is confusing because I can't figure out what this power thing is. I'm going to try and ignore this.

V = (thrustToVelocity * (m_engineVector - drag)) + V

where m_engineVector = localThrust * orientation, but we ignore orientation so m_engineVector = localThrust.

localThrust = ((desiredVelocity - pVelocity) / thrustToVelocity) + Drag therefore

V(t) = (thrustToVelocity * (((desiredVelocity - pVelocity) / thrustToVelocity) + drag - drag) + V

V(t) = (thrustToVelocity * ((desiredVelocity - pVelocity)/thrustToVelocity)) + V

V(t) = (desiredVelocity - pVelocity) + V

desiredVelocity = myBackward * negDesiredSpeed

myBackward = (maxThrust)(backThrustMultiplier)

negDesiredSpeed = maxSpeed * (-1.0f - thrustRatio)

desiredVelocity = (Ts)(-1) * (maxSpeed * (-1- Tb/Ts))

= -1*(Ts)*(Sm)*(1+Tb/Ts)
= -1*((Ts*Sm)+(Tb*Sm)
= -1*Sm*(Ts+Tb)

u=(1.0 - e^(-thrust*thrustToVelocity/maxSpeed)

Why did drag go away?

EDIT: I FIGURED IT OUT. Ok thank god. localThrust goes away.

V = (thrustToVelocity * -drag) + V
= (dT/Mass) * (pVelocity *(u)M/dT)
= pVelocity * ((1.0 - e^(-thrust*thrustToVelocity/maxSpeed)) + V
= V * ((1-e^((-1)(dT/M)/(Sm)))) + V


the KEY to this is that T is in milliseconds, that is to say, T = 1000 = 1 second. At that point it all matches with my experimental values for Boost1 fighters.

In addition the distance traveled by a fighter on one fuel load (without factoring in cruising afterwords) is simply

Code: Select all

(t*e^(t/(SM))*(v+1)+(SM))*e^(-t/(SM))*v
let SM = shipTopSpeed * shipMass = u (to clean it up)

Code: Select all

((v+1)*t*e^(t/u) + (u))*(e^(-t/u))*(v)
multiply the interior by e^(-t/u)

Code: Select all

(v+1)(t) + u*e^(-t/u))*v
where v = the ship's top speed, t = time in milliseconds
Last edited by zombywoof on Wed Mar 20, 2013 6:58 pm, edited 1 time in total.
Image
Don't find fault, find a remedy; anybody can complain.
Cookie Monster wrote:QUOTE (Cookie Monster @ Apr 1 2009, 09:35 PM) But I don't read the forums I only post.
KGJV
Posts: 1474
Joined: Tue Jul 01, 2003 7:00 am
Location: Transilvania

Post by KGJV »

phoenix1 wrote:QUOTE (phoenix1 @ Mar 20 2013, 06:57 PM) also drag += (power*abThrust) *myBackward which is confusing because I can't figure out what this power thing is. I'm going to try and ignore this.
power is the same as explained in the first post.
it's added to drag but only for the "backward part" of the vector since afterburners only give thrust from behind.
Image
zombywoof
Posts: 6522
Joined: Mon Jul 14, 2008 4:59 am
Location: Over the Rainbow

Post by zombywoof »

Yeah I realized that halfway through. I'm going to have to dig back through and see where I $#@!ed up and redo everything but I've been at it for a few hours now so I need to take a break.

Getting functions out of code is rough :P
Image
Don't find fault, find a remedy; anybody can complain.
Cookie Monster wrote:QUOTE (Cookie Monster @ Apr 1 2009, 09:35 PM) But I don't read the forums I only post.
Post Reply