How to simulate a harmonic oscillator controlled by a given signal (not controlled by a sine wave)

I have a table of values ​​telling me how the signal level changes over time, and I want to simulate a harmonic oscillator controlled by this signal. It does not matter if the simulation is not 100% accurate. I know the frequency of the oscillator. I found many formulas, but they all use the sine wave as a driver.

+4
source share
3 answers

I assume you want to do some discrete time modeling. Known formulas require analytical input (see the Green function). If at some point in time you have a power table, typical analytical formulas will not help you.

The idea is this: for each point in time t0, the oscillator has some given acceleration, speed, etc. Now a force acts on it - according to the table that you gave - which will change its acceleration (F = m * a). For the next step t1, we assume that the acceleration remains at this constant, so we can apply the simple Newton equations (v = a * dt) with dt = (t1-t0) for this time interval. Iterate until the desired time range is simulated.

The most important parameter of this simulation is dt, that is, as a fine-grained calculation. For example, you can have 10 steps per second, but it depends entirely on your input parameters. What we are doing here is essentially the Eulerian integration of equations.

This, of course, is not all there is - such simulations can be quite complex, especially. in cases not very good when extreme accelerations, etc. In these cases, you need to perform numerical tests of operability inside the frame, because something "extreme" happens in one frame. Some numerical integration may also be required, for example. Runge-Kutta algorithm . I guess this leads far away at this stage, however.

EDIT: right after I posted this, someone posted a comment on the original question, pointing to “ Verlet Algorithm ”, which is basically an implementation of what I described above.

+3
source

Well, I finally figured it out and wrote a gui application to test it until it works. But my computer is not very happy with what it does 1000 * 44100 times per second, even without gui ^^

Whatever it is: here is my test code (which worked pretty well):

double lastTime; const double deltaT = 1 / 44100.0;//length of a frame in seconds double rFreq; private void InitPendulum() { double freq = 2;//frequency in herz rFreq = FToRSpeed(freq); damp = Math.Pow(0.8, freq * deltaT); } private static double FToRSpeed(double p) { p *= 2; p = Math.PI * p; return p * p; } double damp; double bHeight; double bSpeed; double lastchange; private void timer1_Tick(object sender, EventArgs e) { double now=sw.ElapsedTicks/(double)Stopwatch.Frequency; while (lastTime+deltaT <= now) { bHeight += bSpeed * deltaT; double prevSpeed=bSpeed; bSpeed += (mouseY - bHeight) * (rFreq*deltaT); bSpeed *= damp; if ((bSpeed > 0) != (prevSpeed > 0)) { Console.WriteLine(lastTime - lastchange); lastchange = lastTime; } lastTime += deltaT; } Invalidate();//No, i am not using gdi^^ } 
0
source

All Articles