[PYTHON] Non-linear spring with PyODE slider

I tried to set the force acting on the spring (spring constant, etc.) with an arbitrary function with the slider (ode.SliderJoint) of PyODE.

This is the previous article → Try to double the PyODE slider

1 Motivation

A calculation example using this kind of physics engine is ・ Large number of elements (10 is less) -Springs and dampers are the simplest. And so on.

However, I am dealing with spring / damper systems. There is no point in setting only a simple linear spring. Is it possible to arbitrarily set the spring constant with ODE (PyODE)? If this doesn't work, you will give up using ODE.

Conclusion first

At each time, I found that any force can be passed as a value from the instance method " ʻaddForce ()`` "of"slideJoint``` ". Therefore, you can set the spring constant and damping to your favorite characteristics.

2 Setting method

Directly set the force generated on the slider

First, the part that passes the force generated by the slider as a value. ↓

Give arbitrary driving force with addForce


while() :    ####Time progression loop
    #Omission

    f = spring( j01 , KP, KD )    
    j01.addForce( f )

    world.step(dt)

j01 is a slider or ode.A SliderJoint instance.


 The value determined by the self-made function `` `spring () ``` described later is set as `` `f```.

 Any value can be given as the driving force by the method addForce.

#### **`world.step()Is the time progress of one step of ode`**
```step()Is the time progress of one step of ode

 You can call addForce just before that.

#### Determine the force from the state of the slider
```spring()```Is a self-made function that gets power from the state of the slider.


#### **`Spring / damper function`**
```python

def spring( j, kp, kd=None ):
    r = j.getPosition()
    f = r*r*r * kp
    if None is not kd:
        f += j.getPositionRate() * kd
    return - f

Here, j is the slider (ode.SliderJoint instance) The displacement of the slider can be obtained with the instance method `getPosition ()`. Similarly, the displacement velocity is `getPositionRate ()`.

Here, it is a spring that generates a repulsive force proportional to the cube of the displacement **. (When I tried it with the square, the difference from the linear spring seemed unclear, so I made it the cube.)

3 Results

Visualization by Pygame. ↓ tutorial_1.gif

Black circles are fixed objects. The line represents the position of the spring (slider). The red-brown circle is swaying on the spring.

↓ This is the time change of the height and speed of the red tea circle. y_DT0.0005_kp20_kd0_zeta0.png

KP = 100.0 KD =It is set to 0.


 It ’s worth making it non-linear
 You can see a distorted waveform that is different from a sine wave.


## 4 Summary
```addforce()```I found that I can set the power as I like.
 If this is the case, you can try various things.
 So, I will use this PyODE for a while.


Recommended Posts

Non-linear spring with PyODE slider
Spring damper with PyODE
Try doubling the PyODE slider