A first approach to physical modelling


#1

I'm trying to program a physical model for a spring - mass - spring - mass system.

It looks like this:

No friction and no gravity for now, only horizontal components of acceleration, referring to hooke's law.

This is the current object i'm working on
chaotic osc.axo (2.9 KB)

There are several knobs: time allows to edit the timefactor for the simulation (you should set this to something different than 0 if you want to use the object)
x0 sets the initial displacement for M2 mass.
k, h represent the elastic constants for the two springs
m1, m2 represent the two masses

when the reset inlet is triggered the system restarts the simulation from the x0 position.

The core of the code is this:

A1=(param_h*DX2-param_k*DX1)*281474976710656/M1; //calculating the acceleration in function of the displacement of the spring
A2=-param_h*DX2*281474976710656/M2;

V1+=___SMMUL(A1,param_time); //calculating the resulting speed (i'm doing a quite dumb integration here)
V2+=___SMMUL(A2,param_time);

X1+=___SMMUL(V1,param_time);  //calculating the resulting displacement of the mass (i'm doing another dumb integration here)
X2+=___SMMUL(V2,param_time);

DX1=X1-LA<<4;  //calculating the displacement of the spring relative to the rest position
DX2=X2-X1-LB<<4;

Now, the system is well defined with these equations, there are only some tweaks to be done (i know this because i previously implemented the object with float operations and it worked well, set aside the enormous cpu load).

However, i need to tweak the parameters (and bitshift here and there), but i don't even know where to start.
I already tried some configurations, but they did result in unexpected behaviour (kinda like extremely fast fluctuatioons or absurd dynamic range or bizarre overflowing and acceleration going from +64 to -64 in just 1 cycle.

Can someone help me figure this out?


Awkward plate resonator
#2

Have you tried doing it in floating-point? It might not be too horrendous, given the Cortex M4 has a builtin FPU.

a|x


#3

Yeppp, i tried floating point, but the object would then be extreamely heavy then (like 15-20% dsp load). Using integer operations instead takes the dsp load to about 2-3%


#4

Wow, massive difference...
Must try and learn how fixed-point arithmetic works..

a|x


#5

Did you find that the behaviour of your float-based physical model was more predictable than the fixed-point version?

I ask because isn't what you're modelling an inherently chaotic system? I'm hazy on maths generally, but read a little around Chaos Theory as a youth, and I seem to recall something like this setup being used as an example of a chaotic system. My memory is poor, though, and it was many years ago...

a|x


#6

Ditto. While I know a small amount of DSP, I have been made lazy by Jesusonic's "floating point everything" approach.


#7

I've done quite a lot of coding for graphics in the past (mainly GLSL shaders), and that's floating point all the way. With lots of handy builtin functions for vector arithmetic, matrix manipulation, trigonometric calculations, etc.

a|x


#8

The floating point model was definitely more predictable, but that's because there were no overflows and all variables were nicely scaled.

The result wasn't even that much chaotic, it looked a lot like a low frequency sinewave with some wiggles on top. My intent was however to achieve a decent chaotic system.

I'm gonna try a more systematic approach to it, maybe i can figure out the correct scales.

Also i noticed that ___SMMUL(A,B) produces a different value than A*B


#9

Okay, i succeded!
chaotic osc.axo (3.0 KB)

I replaced regular multiplications with ___SMMUL where possible. I also did a small scaling of variables, since in fixed point multiplication is very sensitive to bad bitshift (they were causing the sign of the acceleration to go from positive to negative with no physical reason)

I'm going to try it in s-rate now :smiley:


#10

That's cool.
What's the advantage of using ___SMMUL()?

Have you tried Johannes cycle-measuring tip to see which uses fewer, just out of interest?

a|x


#11

The main advantage is that now the object works, i'm not totally sure why though :grin:

I assume (but that's just my speculations) it has to do with the truncation of the resulting number (multiplicating two 32b integers with * produces a 64 bit integer, i guess that leaving such a number for further operations might have resulted in screwing with the sign bit.

The cyclecounter test says 500 cycles with the new code, it was 400 with the older one :frowning:
At least this works.


#12

I'm surprised to hear a floating point implementation made such a huge difference. Could you provide me some code so I can investigate why you get such a huge difference?
One possible cause is the (implicit) use of double precision float versus single precision float.


#13

I'm sorry my master, but i didn't keep track of the older code in the process.
However, now that you make me think about it i might have used double precision variables during that experiment. Also i didn't group some operations (meaning that for one equation i performed several multiplications by a constant instead of calculating that number outside the program (because of code clarity)). I don't know if that could sum up to such a waste of cpu, but the s-rate version of the object simply did not work (the patcher would disconnect), and the k-rate was incredibly heavy.


#14

Double precision floating point operations have no hardware support, only single precision, so that 'd cause a huge performance impact. Single precision floating point should no be so bad.


#15

I never thought about physical modelling, but I would be great to have the possibility. For all the programmers like me that don't know much about it, here is a good description how it works: https://hal.inria.fr/hal-00873639/file/Piano-Chaigne-SMAC13.pdf


#16

Interesting paper, it sums up the various aspects of the simulation.
The main problem with physical modelling is the huge amononlinear interactions that come into place when considering materials behaviour under stress. Also, you have to integrate several times (at least two, but sometimes it's even more than that) pretty bad equations. A naive process of integration like the one i did with my model won't take it anywhere: i tried for example to add friction to the model, it worked the opposite i wanted even if i changed the signs inside the equation!


#17

I don't have any programming skills about physical modelling, but did you try to build up on other ideas? My first programming teacher told me that it is always a good idea to take a look on other solutions.

These project may be also nice to get another view:

https://ccrma.stanford.edu/software/stk/

I took a look at GitHub. What about these kind of implementations:

https://github.com/KielGeiger/MIDI-Manipulator

https://github.com/rpavlik/physical-modeling-utilities

https://github.com/OldGregg570/physical-modelling-synthesis

https://github.com/claytonotey/qiano

https://github.com/ptrv/SaM-Designer


#18

Have you tried looking at the source code of Mutable Instruments Elements?
https://github.com/pichenettes/eurorack/tree/master/elements

That might give you some ideas, though it's pretty dense.

a|x


#19

Or Rings:
https://github.com/pichenettes/eurorack/tree/master/rings
Might be a bit simpler, as it's (mostly) just the resonator part of Elements.

a|x


#20

By the way I found some code regarding mass spring system. I'm not sure if that works for you:

http://jean-pierre.moreau.pagesperso-orange.fr/c_mechanics.html

And also a good source might be this free lib:

http://run.usc.edu/vega/