Strange quaternion behaviour [solved]

from direct.directbase import DirectStart
from pandac.PandaModules import *
base.disableMouse()
base.cam.setPos(0,-30,0)
base.cam.lookAt(0,0,0)
normaly = [loader.loadModel("smiley") for i in xrange(5)]
for m in normaly:
    m.reparentTo(render)
strange = loader.loadModel("frowney")
strange.reparentTo(render)
normaly[0].setPos(-3,0,3)
strange.setPos(-3,0,0)
normaly[1].setPos(-3,0,-3)
normaly[2].setPos(3,0,3)
normaly[3].setPos(3,0,0)
normaly[4].setPos(3,0,-3)
def myTask(task):
    q = Quat()
    q.setHpr(normaly[0].getHpr()+Vec3(1,0,0))
    normaly[0].setQuat(q)
    
    q = Quat()
    q.setHpr(strange.getHpr()+Vec3(0,1,0)) #<< HERE
    strange.setQuat(q)

    q = Quat()
    q.setHpr(normaly[1].getHpr()+Vec3(0,0,1))    
    normaly[1].setQuat(q)

    normaly[2].setHpr(normaly[2].getHpr()+Vec3(1,0,0))
    normaly[3].setHpr(normaly[3].getHpr()+Vec3(0,1,0))
    normaly[4].setHpr(normaly[4].getHpr()+Vec3(0,0,1))
    
    return task.cont
taskMgr.add(myTask,"tsk")
run()

why it does not rotate?
Panda 1.7.0, Win 7 x64

Interesting.

I suspect it has to do with pitches beyond +/- 90 degrees being kinda strange. If you go past pointing straight down, the same rotation can be expressed as -90 pitch, 180 H and 180 roll (I think). Which representation panda chooses is arbitrary, but choosing the one with a abs§ less than 90 makes sense. Thus, adding to pitch moves it back toward straight down! Nothing is wrong, and the quats do everything properly. Hpr is simply not 1:1. There are infinite HPR that produce the same orientation, and if you go through a quat and back, you can end up having sudden changes in the HPR values from this.

Anyway, this does work: strange.setP(strange.getP()+1)

I’d just stay away from Hpr if you are going to have high pitch values.

Well, ok, I wrote two procedures to obtain the custom quaternion from H and from P, and… see…

from direct.directbase import DirectStart
from pandac.PandaModules import *
import math
base.disableMouse()
base.cam.setPos(0,-30,0)
base.cam.lookAt(0,0,0)
normaly,normaly2 = loader.loadModel("smiley"),loader.loadModel("smiley")
normaly.reparentTo(render)
normaly2.reparentTo(render)
strange = loader.loadModel("frowney")
strange.reparentTo(render)
normaly.setPos(0,0,2)
strange.setPos(0,0,0)
normaly2.setPos(0,0,-2)

def customQuatFromH(h):
    h = h*0.5
    h = (math.pi/180)*h
    sin_h = math.sin(h)
    q = Quat()
    q.setR(math.cos(h))
    q.setI(0*sin_h) #=0
    q.setJ(0*sin_h) #=0
    q.setK(1*sin_h)
    return q
    
def customQuatFromP(p):
    p = p*0.5
    p = (math.pi/180)*p
    sin_p = math.sin(p)
    q = Quat()
    q.setR(math.cos(p))
    q.setI(1*sin_p)
    q.setJ(0*sin_p) #=0
    q.setK(0*sin_p) #=0
    return q
    
def myTask(task):
    normaly.setQuat(customQuatFromH(normaly.getH()+1)) #<< here it work
    strange.setQuat(customQuatFromP(strange.getP()+1)) #<< and here not work
    normaly2.setQuat(normaly2,customQuatFromP(1)) #<< here work again
    return task.cont

taskMgr.add(myTask,"tsk")
run()

If you really must use quats and Hpr together, do it like this:

q = strange.getQuat()
q2 = Quat()
q2.setHpr(Vec3(0,1,0))
strange.setQuat(q.multiply(q2))

This way the orientation on your object stats a quat the whole time.

Note that the above does happen to have the same effect as this:
strange.setHpr(strange,0,1,0)

Yes, it’s work! Thanks!
I use quaternions to interpolate the data obtained from the network. And I can get the angular velocity only as the Vec3