0
\$\begingroup\$

I'm using the Unity as a physic simulation and I want to gather the data of object position from it. So I put my code about random the force and apply to that object. Also the part that Write the data into .csv format file. The sampling rate that I need is about 360Hz then i decided to set the FixedUpdate to 1/360 ~= 0.002777778. But once i use the DateTime to measure the sampling rate, The unity give the number of points(In my understanding is the number of time date FixedUpdate() have been run because file writing is also in FixedUpdate(). The sampling rate kinda jump between 210 to 410. Please correct me if i'm wrong using this way.

[#Note : I don't care about the low framerate because i just need the position from unity's Physx]

Here's my Time settings. enter image description here

Here's my code to get the current time.

void Start()
{
...
DateTime startTime = DateTime.UtcNow;
DateTime currentTime = DateTime.UtcNow;
...
}

void FixedUpdate(){
...
WriteData()
PhysicsUpdate()
...
currentTime = DateTime.Utc.Now
print("#N Data : " + t + ", Elapsed time : " + (currentTime - startTime));

Here's my results that show the jumping of sampling rate : The sampling rate each passing second periods are 223, 395, 392, 362 (This should close to 360 Data points) enter image description here enter image description here enter image description here enter image description here Thank you.

\$\endgroup\$
7
  • \$\begingroup\$ I noticed that you placed your time measurement code behind your own, not in front of it. Unity has some limited control over when to do FixedUpdates, but it can't guarantee that your code will always take the same time to run. Especially when it involves file access, which is influenced by the OS scheduling. Is it possible that the jitter you are measuring is at least in part caused by your own code? \$\endgroup\$
    – Philipp
    Commented Jul 3, 2020 at 8:10
  • \$\begingroup\$ Also note that Unity is a game engine, not a physics simulator. Its focus is on being good and fast enough for games, not on accuracy. \$\endgroup\$
    – Philipp
    Commented Jul 3, 2020 at 8:14
  • \$\begingroup\$ I think it shouldn't jitter by my code because my code just random the force, apply it to an object and get the position at that time then write to the file. If it have it may came from OS Scheduling. I also trying to set the higher Maximum allowed Timestep to make unity doesn't clipping the physics iteration. \$\endgroup\$ Commented Jul 3, 2020 at 8:27
  • \$\begingroup\$ I think maybe unity will be messy when the FixedUpdate() is set to very low value because I've try to set it equal 0.02 (50Hz) the sampling rate is quite close by varying between ~48-50Hz \$\endgroup\$ Commented Jul 3, 2020 at 8:40
  • 2
    \$\begingroup\$ I think you are underestimating the price for writing to a file. The time it takes can depend on internals of the filesystem and even mechanical constraints (especially when you are still using a classic platter-based hard drive and not an SSD). If you want more accurate measurements, log to memory and then write the contents to a file later or in a separate thread. \$\endgroup\$
    – Philipp
    Commented Jul 3, 2020 at 8:44

1 Answer 1

2
\$\begingroup\$

A common misunderstanding about FixedUpdate is that it runs with a regular rhythm in real time / wall time. ie. that Unity is watching the clock like a hawk, and when the real-time moment for the next FixedUpdate comes around, it puts everything on hold and immediately runs FixedUpdate on that exact moment, then waits for the next moment again.

This is not what this method promises.

Unity runs FixedUpdate with a regular rhythm in game time. At the start of each frame, Unity measures how much game time should have elapsed since last frame, and runs FixedUpdate and the physics step back-to-back some number of times to catch up, advancing the game time in fixed increments with each step.

So, from the perspective of game time, FixedUpdate occurs with perfect regularity. That's how it lets us create consistent game simulations.

From the perspective of the player, who sees the end result after all the catch-up has been done for the frame, the result is a pretty good illusion of consistent frequency. They might observe a judder due to "loose change" time (a bit of extra time has elapsed since the last FixedUpdate, but not enough to run the next FixedUpdate), but this is usually fixable with interpolation. They can also observe slowdown/lag, if the hardware is overloaded and not able to run the updates fast enough for game time to keep pace with real time. This affects the play experience, but not the underlying consistency of the simulation, which still maintains its exact regular frequency in game time.

But you're counting your FixedUpdates with respect to wall time. In wall time, FixedUpdates occur in bursts, generally after their "scheduled time", as the engine plays catch-up at the start of each frame to reach where the simulation should be for the next frame. Especially if your frames are running long because you're asking Unity to do hundreds of physics steps per second, the exact time when those steps are computed will have less and less correlation with the matching wall clock time.

If only the simulation log output matters, then you don't care about when those calculations happened in real time. You just need to know when it occurred within the simulation timeline. So you should be measuring Time.time instead of DateTime.Utc.Now. Or, if 32-bit floating point precision isn't enough for you, you can make your own timer variable that you increment by your fixed timestep in FixedUpdate, to measure your simulation time at any precision you like.

\$\endgroup\$
1
  • \$\begingroup\$ Ok, I did measure the time by using Time.time and it pretty match to the exact sampling rate with the correct number of data points. Thank you very much. \$\endgroup\$ Commented Jul 3, 2020 at 15:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .