Odd behavior (very complex system)

Ok, in this video, it should explain it all,

Moving along axis direction facing when starting engine = fine

rotate 45 degrees, animation playing fine, but Rigid bodies are not syncing to animation …
(EDIT: works fine 180 degrees off axis)


##Jackii and SDFgeoff's code
import bge
import mathutils


obs = bge.logic.getCurrentScene().objects
keyboard = bge.logic.keyboard


armature = obs["Armature"]
own = bge.logic.getCurrentController().owner
scene=bge.logic.getCurrentScene()
P = scene.objects['pelvic']
if not "phys_blendin" in armature:
    armature["phys_blending"] = 20


Ragdoll = [
"head",
"arm1.R", "arm1.L",
"arm2.R", "arm2.L",
"hand.R", "hand.L",
"chest", "spine", "pelvic",
"thigh.R", "thigh.L",
"shin.R", "shin.L",
"foot1.R", "foot1.L"
]


#Thanks Geoff
class rotServo:    
    '''Acts like a servo motion actuator, but rotationally'''
    integral = mathutils.Vector([0,0,0])
    prev_error = mathutils.Vector([0,0,0])
    pid = [30.0, 0.5, 0]
    def __init__(self, owner, torque_max = [0,0,0], torque_min = [0,0,0], rotV = [0,0,0], local=True):
        '''Sets initial values for the servo'''
        self.torque_max = mathutils.Vector(torque_max)
        self.torque_min = mathutils.Vector(torque_min)
        self.rotV = mathutils.Vector(rotV)
        self.owner = owner
        self.local = local
    def update(self):
        '''This function must be run each time you want the servo to update'''
        cur_speed = mathutils.Vector(self.owner.getAngularVelocity(sel  f.local))
        error = self.rotV - cur_speed
        self.integral += error
        derivative  = error - self.prev_error
        self.prev_error = error
        action = error * self.pid[0] + self.integral  * self.pid[1] + derivative  * self.pid[2]
        for i in range(3):
            if self.torque_min[i] != None and action[i] < self.torque_min[i]:
                action[i] = self.torque_min[i]
            if self.torque_max[i] != None and action[i] > self.torque_max[i]:
                action[i] = self.torque_max[i]
        self.owner.applyTorque(action, self.local)
        


def col(colliders):
    if not colliders.name in Ragdoll:
        armature["last collided object"] = colliders.name


def main():
  control = armature["Control"]
  for part0 in Ragdoll:
    part = obs[part0]
    cont = obs[part.get("prop", 0)]
    partrot  = part.worldOrientation
    controt  = cont.worldOrientation
    dif = mathutils.Vector((controt * partrot.inverted()).to_euler())
    posdif = cont.worldPosition - part.worldPosition
    if armature["physics"] == False:
        part.applyMovement(posdif/armature["phys_blending"], 0)
        part.applyRotation(dif/armature["phys_blending"], 0)
        if not part.mass == 0:
            #part.setCollisionMargin(0.05)
            part.setParent(cont,0,0)
    else:
        if part.mass == 0:
            #part.setCollisionMargin(0.05)
            part.removeParent()
        armature.worldPosition = obs["pelvic"].worldPosition
        
        stren = part.get("stren", 2)
        pvel = part.get("vel", 30)
        vel = dif * pvel * control
        torque = stren*50 * control
        part["rotservo"] = rotServo(part, torque_max=[torque,torque,torque], torque_min=[-torque,-torque,-torque])
        part["rotservo"].rotV = mathutils.Vector(vel)
        part["rotservo"].local = False
        part["rotservo"].update()


        part.setAngularVelocity((part.getAngularVelocity() * 0.9)*control, 0 )
        
        ##In real people momentum can be absorbed by the core, without reaching a limit of 6dof
        V=part.worldLinearVelocity.copy()
        part.worldLinearVelocity=part.worldLinearVelocity*  .8+P.worldLinearVelocity*.2
        P.worldLinearVelocity=P.worldLinearVelocity*.8+V*.  199
        AV=part.worldAngularVelocity.copy()
        part.worldAngularVelocity=part.worldAngularVelocit  y*.9+P.worldAngularVelocity*.1
        P.worldAngularVelocity=P.worldAngularVelocity*.8+A  V*.1
    if not "colcallbacks" in part:
        part["colcallbacks"] = part.collisionCallbacks.append(col)
        

I don’t see anything that would mess with it based on world orientation…

My code is just aiming the feet ik targets, and playing action using scale, but I don’t see anything there either that should cause this,



##scale RotEmpty with ik targets playing walk action parented to it
import bge




def main():


    cont = bge.logic.getCurrentController()
    own = cont.owner


    own.localScale=(1,own['StrideLength'],own['StrideHeight'])
main()




## placing the empty that a cube is parented to the cube is the target of track to of RotEmpty and scale stride
import bge




def main():


    cont = bge.logic.getCurrentController()
    own = cont.owner
    scene=bge.logic.getCurrentScene()
    SY=scene.objects['ScaleY']
    SZ=scene.objects['ScaleZ']
    target=scene.objects['Target']
    sens = cont.sensors['Ray']
    Hp=own.worldPosition.copy()
    Hp.x=sens.hitPosition[0]
    Hp.y=sens.hitPosition[1]
    Hp.z=sens.hitPosition[2]
    D=own.worldPosition-Hp
    D=D.magnitude
    if sens.positive:
       target.worldPosition=sens.hitPosition
       SY['ScaleY']=.75-(D*.1)
       SZ['ScaleZ']=.5+(D*.1)
    else:
       target.worldPosition=own.worldPosition
       target.localPosition.z=target.localPosition.z-1.5
       SY['ScaleY']=.5
       SZ['ScaleZ']-1
    
main()



all the rest are camera related…

45 degree = makes a good zombie walk

theres alot going on there but seeing that its right at 0 ,throws off as you angle more, then realigns at 180…somethings not scaling right or getting wrong scale from a parent somewhere…i assume youve applied and checked and all your scales and copy scales and contraints and basics?. The cubes look like they’re going to the right spot so maybe the bottom code is fine.

best i can tell here in the top part of the top script:

    part = obs[part0]
    cont = obs[part.get("prop", 0)]
    partrot  = part.worldOrientation
    controt  = cont.worldOrientation
    dif = mathutils.Vector((controt * partrot.inverted()).to_euler())
    posdif = cont.worldPosition - part.worldPosition

and here a little further down in the same script:


stren = part.get("stren", 2)
pvel = part.get("vel", 30)
vel = dif * pvel * control
torque = stren*50 * control

it looks like its setting some strengths and velocities based off of orientations, and applies them further down. You could start hacking away there if youve checked the basics. I dont understand enough about vector maths to be any real help though

Edit: After thinking about it, and its hard to tell without playing with your system and seeing how it works, stride strenghts and stuff shouldnt change based on the angle/heading your facing, your stride would be a constant regardless which way your facing. all that changes is your heading, maybe something getting a scale applied to it from an orientation that doesnt need to. IOW maybe something needs to be a constant rather than formulated from orientation

Well, I applied what I learned back to the old rig :smiley:

at least I have something to do while I get help.

I don’t understand the PID controller that well,

I am scaling an action bit the actionScalerRotator is in line with said action in rotation, so it should be constant :expressionless:

I fixed my walk cycle from what I applied to the new rig :smiley:

The problem is with collision bounds. I increased them on the legs especially in the last version I’ve sent you to obtain stability, as they were the cause of glitching the ragdoll. I’d suggest resizing the ragdoll up. Though I’ll be working on a hard-coded procedural locomotion system for it soon.

Nice to hear Jackii :smiley: