Welcome to Keen Software House Forums! Log in or Sign up to interact with the KSH community.
  1. You are currently browsing our forum as a guest. Create your own forum account to access all forum functionality.

How to negate gravity with a missile (forward thrust only)?

Discussion in 'Programming (In-game)' started by Jon Turpin, Oct 13, 2017.

Thread Status:
This last post in this thread was made more than 31 days old.
  1. Jon Turpin Apprentice Engineer

    Messages:
    162
    I'm trying to miniaturize my intercept script from a drone into a missile. In order to drop excess weight to increase acceleration and decrease time to target, I want to drop all but forward-propelling thrusters. As such, I need to figure out how to negate gravity (and drift). What is the algorithm I need to calculate this? For example, currently I'm working on this:
    Code:
    		 /
    	       / V
    	a -> / 	  
    F ->	M> ---------------------> []
    	|	     d		   T
    	v
    	g
    
    F = ma
    a = f/m
    g = -9.81m/s^2
    d = displacement vector
    V = aim vector
    T = target
    M> is the missile

    At time Zero, initial velocity is zero, with ~20m/s^2 acceleration, so V will need to be the displacement vector plus ~44° up (inverse of the g vector) to keep from falling to the ground. What is the formula for what V is with respect to time? I only need to negate 9.81 m/s worth of downward acceleration at ant given time, but I can't figure out the equation for it.

    Also, is there a way to have the missile maintain a certain altitude? Such that it doesn't collide with a hill if that ends up being the shortest path to the target?

    I suppose I can always go with a ballistic approach and use D = P + Vo(t) + 1/2(a-g)t^2 and derive an equation to find the aim vector in order for gravity to pull it down to the target's position, but I'd rather a direct approach if possible. Thank you in advance!
     
    Last edited: Oct 13, 2017
  2. Arcturus Senior Engineer

    Messages:
    1,649
    Note that if you thrust against the speed limit, the grid accelerates as much as it can in 1/60 of a second and then the velocity is capped at the speed limit while keeping the direction of the velocity vector the same. Also note the planet's curvature is significant. Conventional kinematics equations won't work here.
     
  3. Jon Turpin Apprentice Engineer

    Messages:
    162
    This should be fine given the equation I'm looking for, as the aim vector calculation would only use the current velocity in time to figure out the pitch. When the velocity stops changing, the pitch remains at the correct angle to keep gravity from pulling the missile down prematurely.

    I disagree, here. The diplacement vector already takes into account the curvature, as the ground is curving up toward the vector and will be a shorter distance to its normal at the target's end than it is at the missle's. In fact, if you target the top of a structure over the horizon, the displacement vector calculated to the center position will go through the planet. The missile trajectory will be the same arc (with the calculated gravity negation) either way. Here's what I'm thinking:

    EDIT: I should say - the arc will be relatively the same, given that both the targeting ship and the target ship/structure are near the ground at time of launch.

    Code:
                __
         V /          \
      /          d          \
    M>-----------------------{}
                 ______ ------     
    ______ ------  ground
    
    I have a working prototype using downward thrusters, as the ship is kept afloat via the dampeners, but it's too bulky, even with minimal blocks - I'd like to streamline it to where I have just one or two lines of blocks that include everything needed for the guidance system. I'm pretty sure I've seen videos of SAMs and I know @Whiplash141 has worked with AAMs, so the calculation has to be out there, somewhere...
     
    Last edited: Oct 13, 2017
  4. suspensionrailway Trainee Engineer

    Messages:
    5
    Well one thing I like to do is calculate the max angle away from gravity I can shift my ship while negating gravity. This can be calculated by doing cos(angle) = gravityacceleration/maxthrusteracceleration. Then you can use some kind of script to make your thruster point that angle. That will then only negate gravity, and the rest of your thrust will be dedicated to lateral thrust. The amount of lateral acceleration remaining can be calculated by doing sin(angle) * maxacceleration. By the way, the discord is a much faster way to get these kinds of questions answered. If you need more help, my discord name is the same as my forum name.
     
    • Informative Informative x 1
  5. Jon Turpin Apprentice Engineer

    Messages:
    162
    Thank you!

    Will do :)
     
  6. Whiplash141 Junior Engineer

    Messages:
    958
    Sorry, I got bogged down this week, and I meant to show you how to cancel out unwanted velocity:
    I simply reflect my current travel vector (velocity) over my desired heading vector. This applies my thrust opposite of my "drift" and seeks to cancel out unwanted lateral thrust.

    var overSteerGain = 5.0; //typically a good value. This is what I use
    var adjustedHeading = VectorReflection(myVelocityVector, desiredHeading, overSteerGain);

    A vector reflection is defined by:
    Code:
    //Whip's Vector Reflection Method
    Vector3D VectorReflection(Vector3D a, Vector3D b, double rejectionFactor = 1) //reflect a over b  
    {
        Vector3D project_a = VectorProjection(a, b);
        Vector3D reject_a = a - project_a;
        return project_a - reject_a * rejectionFactor;
    }
    
    Vector3D VectorProjection(Vector3D a, Vector3D b) //proj a on b  
    {
        if (Vector3D.IsZero(b))
            return new Vector3D(0, 0, 0);
    
        Vector3D projection = a.Dot(b) / b.LengthSquared() * b;
        return projection;
    }
    

    This is reasonably effective for canceling out unwanted drift as it serves as a Proportional controller where "rejectionFactor" is my P gain.
     
    • Informative Informative x 1
  7. Jon Turpin Apprentice Engineer

    Messages:
    162
    @Whiplash141 You've no reason apologize, my man. I figured I'd throw a line a line and hoped you'd bite lol.

    I was actually looking at your reflection method yesterday (looked for where you checked for gravity in the script, and figured this might have something to do with it) but I didn't really understand what it was doing - until now :D

    Do you adjust the rejectionfactor? I need to find a good tutorial on the PID controller. I get the concept but not so much the method. Took me a while to get it right on the intercept drone :p

    This method is so much simpler than what I was thinking, as usual. Thank You!
     
  8. Whiplash141 Junior Engineer

    Messages:
    958

    Yeah, I've found from empirical testing that 3-5 is typically pretty good for gravity.

    :p Told ya approximations are the bomb-diggity
     
    • Funny Funny x 1
  9. Jon Turpin Apprentice Engineer

    Messages:
    162
    So I implemented the reflection in the script last night, but couldn't get it to keep the missile from falling. I will note that I'm using a large grid setup, with 4 small atmo thrusters facing backward.

    I first started with a simple reflection, with no oversteer, and then ramped it up to 8. From 1-5, little if anything changed. As I approached 8, it just started spinning. I haven't crossed off bugs in my code, yet, as I only had a couple of hours to play around with it. But I would have thought that I would SEE the adjustments of the grid with the reflection (at lower values of oversteer, that is - seems to go from nothing to too much). Here's my setup:

    Code:
    public void Intercept()
    {
        var fwdVector = remote.WorldMatrix.Forward;
        var lftVector = remote.WorldMatrix.Left;
        var upVector = remote.WorldMatrix.Up;
    
        bool inGravity = remote.GetNaturalGravity().LengthSquared() > 0;
    
        if (inGravity)
        {
            Vector3D myVelocityVec = remote.GetShipVelocities().LinearVelocity;
            interceptVector = CalculateHeadingVec(myVelocityVec, interceptVector);
        }
    
        //---Get pitch and yaw angles 
        double yawAngle; double pitchAngle;
        GetRotationAngles(interceptVector, fwdVector, lftVector, upVector, out yawAngle, out pitchAngle);
    
        //---Angle controller
        double yawSpeed = yawPID.Control(yawAngle);
        double pitchSpeed = pitchPID.Control(pitchAngle);
    
        //---Set appropriate gyro override 
        ApplyGyroOverride(pitchSpeed, yawSpeed, rollSpeed, gyros, remote);
    
        foreach (var thruster in fwdThrusters)
        {
            thruster.SetValueFloat("Override", float.MaxValue);
        }
    }
    
    
    Which is run every tick as long as a target is locked. I noticed in your code you only do the reflection is the velocity lengthsquared is >100, so maybe I just need more altitude? I'm guessing that when I used that line, the missile likely didn't reach the needed velocity before crashing.
     
    Last edited: Oct 16, 2017
  10. Whiplash141 Junior Engineer

    Messages:
    958
    Oh I suppose I forgot a vital component to this logic! In my script, I set my target vector to be only (2 * missileVelocity) meters (or just 200 m) in front of my current position.

    I accomplish that by the following:
    Code:
    var normalizedDirectionToTarget = Vector3D.Normalize(targetPos - myPos);
    var targetVec = normalizedDirectionToTarget * 200;
    var adjustedTargetVec = myPos + targetVec;
    
    This makes the missile reflect over a vector that is influenced much more by heading errors than the total target vector.
     
  11. Innoble Apprentice Engineer

    Messages:
    238
    Missiles only need to smack into a target, so they don't need to hang still in the air. It is even harder to use 1 directional thrusters to navigate and stop something dead and just make it hover at a targeted GPS coordinate. I made a drone a year ago that could do this. I used critical damping (solution of the wave equation) to make it stop without overshooting. If you don't do this, it is going to oscillate forward and backwards once it gets to a spot it is supposed to hover above. I'll try to post the script next week or so when I have some time. The script needs to be adapted with all the PB changes.
     
  12. Jon Turpin Apprentice Engineer

    Messages:
    162
    The hovering wasn't the issue, it was just some bugs in the code (I forget the exact fix). Once I got the math right, everything fell into place :) Ty for the reply, tho!
     
  13. Ronin1973 Master Engineer

    Messages:
    4,845
    I designed some pathing for drones of mine that can circumnavigate a planet. The key is detecting the planet's true center in relation to the game world. I believe this can be pulled via the remote block either directly. I have a set cruise altitude. I take the vector of the planet center through the remote of the drone/missile to establish where the first waypoint should be. I then calculate the objective in the same manner to create a terminal list of waypoints. The ends of both vectors are tied together as a line segment, then the distances are divided into predefined lengths (like 10km or so). Each of these points along the line then become reference points to draw additional vectors through that terminate at the desired cruise altitude. Those points are then fed into the remote block including the terminal waypoints.

    If you've painted a target and have its current location referenced to the planet center, you can plot and update a course of travel based on the target. In atmosphere, I think I'd want the missile to travel well above the surface until it gets close to the target and then begin to descend to intercept. An exact path isn't critical until you're within 1000 meters or so of the target. So I think a fair degree of error is acceptable until you're close to terminal range.
     
Thread Status:
This last post in this thread was made more than 31 days old.