Announcement

Collapse
No announcement yet.

Measuring a vehicles relative acceleration?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Measuring a vehicles relative acceleration?

    I'm trying to figure out how to measure a vehicle's acceleration, but I'm running into two problems:

    1) Acceleration values log fine for normal Pawns (not in a vehicle), but trying to log the vehicle's values gets 0 all the time.

    2) The acceleration values are absolute, meaning they follow the world's XYZ values instead of the Pawn's rotational XYZ values.


    I'm thinking I can use VSize(Velocity), then compare the rotation of the velocity with the last measured value against the pawn's rotation, and use sin/cos to figure out acceleration for X and Y, but I'm hoping there's an easier way.

    #2
    I know that vehicles dont use the Acceleration variable of Actor, but I'm not positive how exactly they achieve their acceleration.

    However, I do know that it has a lot to do with the TorqueCurve properties. This "curve" defines points on the line, between which the "curve" is calculated using standard physics, which produces a smooth curve. The slope between point x1, y1 and x2, y2 is the rate of acceleration between these values. The acceleration is actually, I think, a reaction to the friction of the wheels on the ground. The faster they spin, the more friction they produce, which is what actually makes the car accelerate (as is true with real physics).

    More info:

    http://udn.epicgames.com/Two/KarmaCarCreation

    For your other method, the difference in velicity divided by the time between the two measurements is equal to the acceleration. A = (V2 - V1)/DeltaTime, where V1 is the previous velocity, and V2 is the current. This works with both numbers and vectors, giving you the acceleration vector you want.

    Comment


      #3
      Also you can turn the Acceleration to face the rotation (so that it faces the direction the Pawn is facing and maintains its magnitude) using Acceleration = Acceleration >> Rotation;. This gives you a vector turned to point in the direction of a rotator (correct me if I'm wrong), thus accelerating the pawn towards its rotation.

      Comment


        #4
        Re: Measuring a vehicles relative acceleration?

        Originally posted by Angel_Mapper
        I'm thinking I can use VSize(Velocity), then compare the rotation of the velocity with the last measured value against the pawn's rotation, and use sin/cos to figure out acceleration for X and Y, but I'm hoping there's an easier way.
        I don't know about a more direct route than comparing velocities, but you should not need to muck about with VSize and/or sin/cos if you're only interested in the X/Y components. (Velocity - PreviousVelocity) >> Rotation gives you a relative acceleration vector from which you can read X and Y directly, no?

        Comment


          #5
          No, as I said, you need to divide by DeltaTime between the two velocities

          Comment


            #6
            The acceleration values are absolute, meaning they follow the world's XYZ values instead of the Pawn's rotational XYZ values.
            So what you want then I guess is the amount of "speed up/down" in the direction of travel? In other words, you want to see how much the vehicle builds up linear speed, vs. how much it builds up turning speed? I guess you want to use local axes relative to the vehicles velocity vector and orthogonal deviation from that velocity vector. I can't recall the official terms for such an axes, sorry :P.

            Here is what I am thinking you are talking about:


            v1 is Velocity measured at time 1 (called myLastVel in the code).
            v2 is Velocity measured at time 2 (called Velocity in the code).
            "a" is the acceleration vector, which is the difference between v2 and v1 (called myLastAccel in the code).
            "dev" is the the "deviation" axis (someone please tell me the correct term!). By deviation i mean, away from the linear direction.

            The calculations are done with respect to v1.

            The *scalar* projection of the acceleration vector "a" onto the velocity vector v1 should give you the linear speed.
            The *scalar* projection of the vector "a" onto the deviation access should give you the speed deviating away from linear direction.

            You mentioned sin and cos, and this diagram shows why they make sense here, but you can use them implicity since they are equivalent to taking the dot and cross product and doing some other kung fu.

            proj_v1(a) = (a dot v1)/|v1|. (Called myLinearSpeedDelta in the code).
            proj_dev(a) = |(a cross v1)/|v1|| (Called myTurningSpeedDelta in the code)

            Code:
            var Vector myAccel;         // vector (true) acceleration 
            
            // scalar "acceleration" (not just linear or turning, but both, in other
            // words, along the actual acceleration vector, not the along the
            // velocity vector
            var float mySpeedDelta;
            
            // Component of speed linearly
            var float myLinearSpeedDelta;
            
            // Component of speed in turning
            var float myTurningSpeedDelta;
            
            // Amount of time passing between checks
            var float sampleInterval;   
            
            setTimer(sampleInterval, true);
            ....
            
            Timer()
            {
            
            ....
            myAccel = (Velocity - myLastVel)/accelCheckInterval;
            mySpeedDelta = VSize(myAccel);
            
            // Get acceleration component along velocity axis
            myLinearSpeedDelta = (myAccel dot myLastVel)/VSize(myLastVel);
            
            // Get acceleration component along deviation axis
            myTurningSpeedDelta = VSize((myAccel cross myLastVel)/VSize(myLastVel));
            
            ....
            // display stuff
            ....
            
            // Save velocity vector for calcing the differential next sample.
            myLastVel = Velocity;
            }


            I THINK! Anyone see errors? :P


            All of this though still treats the vehicle like a point object, disregarding its rotation. If you would like to get negative speed up/down values for driving in reverse, and 0 speed up/down values for being bumped laterally, then you need one more step, which is to first get the *vector* projection of Velocity onto the vehicle's rotation vector. For that, just do this:

            Code:
            myDirectionalVel = (Velocity dot Rotation) * Rotation
            and then use myDirectionVel instead of Velocity in the code.

            Comment


              #7
              Alright, thanks everyone. Going to try a few things and see if I can get it working.

              btw, are there any references to how >> and dot/cross etc work?

              Comment


                #8
                There are some infos on dot and cross in the wiki (useful vector functions), but I've never seen any info at all on >> or <<, I just figured out what it does through trial and error.

                Comment


                  #9
                  I do not believe that >> or << are what you want by the way.

                  Those just rotate a vector by a certain angle.

                  WHat you want are *scalar* projections, which tell you using a numerical magnitude how much two vectors "share in common" so to speak, and *vector* projections, which tell you the same thing in vector form.

                  http://en.wikipedia.org/wiki/Dot_product
                  http://en.wikipedia.org/wiki/Cross_product <---- not as useful for understanding *why* you want to use cross in this case... just read the Dot_product page mainly and realize that cross works the exact same way except that it is equivalent to a result using sin, instead of cos, and it returns a vector technically perpendicular to the two factor (so you just unvectorize it!). THe scalar magnitude of that funky vector is all you want out of it, so think of it as a sin version of dot for your purposes.


                  Why do you want to use dot and cross instead of sin/cos??

                  Becase they are *far* faster to calculate since they each have a simple addition & multiplication equation that returns results equivalent to use sin or cos, and you don't need to worry about figuring out the angle between vectors that you would need to pass to sin/cos, since they do that automatically for you .


                  I just remembered the name of the local axes system: it's called a "TNB Frame", also known as the "Frenet Frame" http://en.wikipedia.org/wiki/TNB.

                  T is approximated by the unit vector in the direction of V1 (myLastVel) in my example.
                  N is what I was calling the "deviation" axis,
                  B is not discussed in my post. Indeed, I assumed you were treating the vehicle more or less as a ground vehicle, and ignoring vertical speed altogether. Is this correct?

                  What I was calling "TurningSpeed" is actually related to "Curvature" exept that Curvature depends only on the shape of a curve and not on its parameterization (so in other words, the shape of the path taken by the vehicle without respect to time t -- therefore TurningSpeed is a more useful concept for you than Curvature is).

                  However, that bit of information won't help you understand ANYTHING, and will lead you down a rabbit's hole that is very painful :P. Stupid 3D Calculus classes still bring back tortuous memories. Just know that is what it is called for future reference when talking about it, but don't bother to actually look up "TNB frame" unless you want to have nightmares for the next month.

                  Comment


                    #10
                    Yeah, ignoring vertical speed for the most part. Thanks for the help, I'll let you know how it goes!

                    Comment


                      #11
                      In a UT99 map I was working on, I was doing all kinds of acceleration/velocity stuff with a custom mover class that would follow more advanced PathPoints (or whatever they were called), since Epic's version really sucked (they never finished the code).

                      At any rate, you may run into some very nasty results if you do not stick to a rigid timing protocol. Use Timer() for example, not Tick() [don't even bother trying to use Tick() with deltaTime].

                      Well maybe it doesn't matter for just printing out stuff the engine is doing natively, but if you ever want to set velocity or acceleration, or whatever, it will lead to very nasty differential instability just from slight numerical inexactness....I know that's vague, but just follow this rule of thumb: Time-based things should be done in "realtime" (rigid repeated time frames). I think that will be helpful in any project that has time-based things in it (including vehicles and so on).

                      Comment


                        #12
                        Na, I'm just reading values, not changing anything. And using Tick for what I'm doing lags the game, so I set a fast looping timer.

                        Comment


                          #13
                          Good . It's easier to code/debug that way anyway.

                          Comment


                            #14
                            One problem, dot isn't taking rotators, and:

                            DirectionalVelocity = (Velocity dot vector(Rotation)) * vector(Rotation);

                            Is just giving me the velocity in world coordinates again, not relative to the pawn. :bored:

                            Comment


                              #15
                              Ok, slight change in plan. Now the design calls for only getting the acceleration when you run into something. I'm trying to use TakeDamage's momentum variable, but it's always logging 0, I'm assuming because you're not being hit with a weapon. Any way to get some XYZ values? I've tried Location - HitLocation, but the values are always so similar that I don't think it's reliable enough to use.

                              Comment

                              Working...
                              X