Search Unity

Determining the speed of an object in MPH

Discussion in 'Scripting' started by rocket5tim, Aug 18, 2009.

  1. rocket5tim

    rocket5tim

    Joined:
    May 19, 2009
    Posts:
    242
    Hello. I'm trying to determine the speed of a rigidbody when it reaches a specific point (like a speed trap). The object will always travel a specific distance (distance is known) but you can take any amount of time to get there so speed = distance/time doesn't get the correct speed at the trap. For example:

    Code (csharp):
    1. var speedText : GUIText;
    2. function DisplaySpeed() {
    3.     theTime = Time.time;
    4.     vehicleSpeed = 0.5*3600/theTime;
    5.     speedText.text = vehicleSpeed.ToString("0.#.0");
    6. }
    I've seen some other car scripts (car.js from the networking tutorial and jcar.cs) using the following to calculate KPH in real-time, but even that doesn't appear to return an accurate speed.

    Code (csharp):
    1. rigidbody.velocity.magnitude *3.6;
    How was the "3.6" derived and how can I figure out the correct formula for MPH?

    Here's a super simple example of how I'm moving my object/car. Note that my "car" is just a cube/rigidbody without any wheels etc.

    Code (csharp):
    1. function FixedUpdate() {
    2.     Rigidbody.AddRelativeForce (0, 100, 0);
    3.     Debug.Log(rigidbody.velocity.magnitude *3.6);
    4. }
     
  2. perlohmann

    perlohmann

    Joined:
    Feb 12, 2009
    Posts:
    221
    I would prob implement some sort of trigger system where when you enter the start trigger the "timer" will start and when you enter/leave the stop trigger the timer will stop. If you know the distance you can calculate the velocity. cant tell you how as this is dependend on you unit size and scale etc.

    NB! it might be needed to "rewind" the car to the exact time of entry in the start trigger if you are dealing with short distances and high velocities.

    well I presume that 3.6 is a conversion from m/s to km/h (60*60/1000) not sure though, but it is a good guess.

    //perlohmann
     
  3. Jim Offerman

    Jim Offerman

    Joined:
    Jul 17, 2009
    Posts:
    177
    I'd second that guess - how could it be anything else?

    To go from km/h to MPH, you multiply that number by 0.621371192 (thanks Google).

    To go straight from m/s to MPH, use 2.2369362912.
     
  4. Adrian

    Adrian

    Joined:
    Apr 5, 2008
    Posts:
    1,065
    Using time = distance/time will give you the average speed of the object over the distance traveled.

    Using rigidbody.velocity.magnitue will give you the speed of the object for the current frame.

    The units in Unity are generic and what they represent depends on what you choose. A convention is to use 1 unit = 1 meter but you could easily use 1 unit = 1 mile.

    The only constraints are that your coordinates should neither get too large or too small (because you'll loose precision) and that the physics engine expects that one unit is one meter (because big objects don't behave the same as small objects).

    So, before we could tell you how to convert rigidbody.velocity.magnitue to mph you have to tell use what units you are using in your game. i.e. how many units is the known distance and what does that number represent (meters, feet, miles?)?
     
  5. rocket5tim

    rocket5tim

    Joined:
    May 19, 2009
    Posts:
    242
    Thanks for the fast responses! I played around with this a lot more last night after posting and found that multiplying the magnitude by 100 gives me what appears to be a fairly accurate MPH conversion.

    My object travels on the Y axis from -4.03 to to 3.87 (7.9 Unity units). I'm considering that distance to be 1/4 mile. My object has Mass = 100 and Drag = 0.25.

    To test my multiplier, I went to dragtimes.com which has tons of drag racing time slips that provide quarter mile elapsed times and speeds.

    With my car being driving by: car.AddRelativeForce (0, 131, 0), I recorded the elapsed time and speed at the finish line at: 4.580 seconds @ 332.24 MPH which compares closely to an actual time slip example: "4.498 @ 333.740, Dragster Rear Engine top fuel by Brandon Burnstein".

    I'm not sure why this turns out to be true, I just took a stab in the dark and came up with something that appears to be accurate. Any thoughts on how/why or if there's a way to be sure that my math is adding up properly?

    Here's the updated code:

    Code (csharp):
    1. function FixedUpdate() {
    2.    Rigidbody.AddRelativeForce (0, anyForce, 0);
    3.    Debug.Log(rigidbody.velocity.magnitude *100);
    4. }
     
  6. Adrian

    Adrian

    Joined:
    Apr 5, 2008
    Posts:
    1,065
    If 7.9 units are 1/4 mile, then one unit would be 0.0316 miles or 167 feet.

    That's also the unit you get for velocity, i.e. 1 menas 167 feet per second or 114 miles per hour. Multiplying by 100 really gets you pretty close.

    Though, instead of just correcting the odd unit scale you've currently got by multiplying I'd suggest actually rescaling your whole scene so that you get sensible base units.

    I'd scale your scene up so that the base unit is nearer to what the physics engine expects. i.e. to make 1 unit = 1 yard you would need to scale your scene by 55.
     
  7. rocket5tim

    rocket5tim

    Joined:
    May 19, 2009
    Posts:
    242
    Thanks for the advice on scale, Adrian. Using a fraction for my base was clearly not ideal.

    I've scaled up my scene so that my 1/4 mile is now 20 units which = 66 feet per unit. I can't imagine scaling it up further since the bigger the track gets, the bigger my cars need to be (or they'll be too small to see -- it's a "scale" 1/4 mile afterall). I notice now that I need to apply a lot more force to get my car moving at the same speed it was going before (131 before, 331 now) -- but keep in mind that I'm simulating a car that has ~7000 hp.

    I haven't found any documentation on rigidbody.velocity.magnitude (or even just magnitude on its own). From what you guys are saying, it sounds like it reports back the objects velocity in meters per second. If that's true, my speed trap is clocking the car at 8.459 m/s which when multiplied by 2.236 only comes out to 10.267 MPH but the speed I'm expecting should be in the 333 MPH range. Is there an additional calculation I'm missing or am I correct in assuming that I need to fudge the multiplier to get the scale speeds I'm looking for?
     
  8. perlohmann

    perlohmann

    Joined:
    Feb 12, 2009
    Posts:
    221
    The return is in units per second. so if 1 unit = 1m then yes else no.

    rigidbody.velocity is a vector going from 0.0.0 out to another point (depending on the direction and speed of the body) what magnitude does is just taking the length of that vector.

    you can do the same by doing it like this:
    Code (csharp):
    1.  
    2. //v is the velocity vector.
    3. float magnitude = Mathf.Sqrt((v.x*v.x)+(v.y*v.y)+(v.z*v.z));
    4.  
     
  9. pavlito

    pavlito

    Joined:
    Nov 27, 2007
    Posts:
    136
    Maybe im getting this wrong, but documentation and Adrian made me think...

    "If you add or subtract to a value every frame chances are you should multiply with Time.deltaTime. When you multiply with Time.deltaTime you essentially express: I want to move this object 10 meters per second instead of 10 meters per frame." - http://unity3d.com/support/documentation/ScriptReference/Time-deltaTime.html

    so, to get the correct speed in mph you should use

    Code (csharp):
    1. rigidbody.velocity.magnitude * 2.237 * Time.deltaTime
    2.237 is from wolframalpha.com

    Hope this helps :)