0
$\begingroup$

I'm new to blender scripting, but not to blender or python. I am trying to set up a rotary inverted pendulum. The initial state of the pendulum is upright with an angular velocity of 0. I would like to run a simulation a few hundred times with different parameters and need to be able to "reset" the pendulum to its initial state after each episode.

I am aware of the bug/feature of setAngularVelocity in which you have to set to a vector of very small numbers and not 0 to stop a rotation, however it still does not work for me.

Here is the code that I use in a module. The function is called every other frame with an "Always" actuator. So the pole should fall freely for max_steps steps and then be stopped and brought upright. When I run the game engine it only acts like this the first time.

# Take action
base.setAngularVelocity([0,0,data.action], True)

# Get angle and speed
xyz = pole.localOrientation.to_euler()
roty = math.degrees(xyz[1])
spd = pole.getAngularVelocity(True) # True for local
spdy = spd[1]
print(spdy)

[...stuff...]

data.step   += 1

if data.step > data.max_steps or R == -50:
    data.action = 0
    data.step = 0
    pole.worldOrientation = ([1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0])
    base.setAngularVelocity([0.00001,0.00001,0.00001], True)
    pole.setAngularVelocity([0.00001,0.00001,0.00001], True)

Edit: I forgot to mention that setting the angular velocity for the base on line 2 works fine, but not in the if statement

$\endgroup$
1
$\begingroup$

It is not a bug. It is a feature ;).

Sometimes it is an annoying feature.

I tried various methods to get zero velocity.

A) parent/unparent ... restores the previous velocity.

B) disable/enable physics ... restores the previous velocity.

C) I found one (not so nice) way by experimenting:

def stop(owner):
    owner.setLinearVelocity([0,0,1])
    force = [0,0,-50.174276 * owner.mass]
    owner.applyForce(force)

It shows zero velocity with even 24 digits. I can't tell if that is really the case, but it looks like that.

Be aware, this velocity appears within the next frame as apply frame will not effect the object immediately (0,0,1) at frame t and (0,0,0) at frame t+1. Be aware this force counters gravity (9,8) for this one frame too.


[edit] With taking gravity into account I get this:

def stop(owner):
    owner.setLinearVelocity([0,0,1])
    gravity = owner.scene.gravity
    force = -gravity.copy()
    force.z = (-59.974275 - (gravity.z)) * owner.mass
    owner.applyForce(force)

The frame rate has some influence too (I would expect -60 not -59.974275). But I can't find a formula on that.

Maybe it helps

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.