#1
|
|||
|
|||
Problem with getEuler and setEuler
Hi
I am working on a little code, where I have a small kinematic that I want to move with some key´s. When a key is pressed, a function calculates all the necessary new angles of all my bodys. This function gives these values to a second function. This second function does the following with these values for each body. Code:
euler = body.getEuler(viz.ABS_GLOBAL) euler[1] = valuefromfunction body.setEuler(viz.ABS_GLOBAL) when I print out the values for valuefromfunction and the getEuler variable, the values are ok. But the vizualisation of the body alternates between two positions, one lets say 88° and the second 92°. But I think it is only a vizualisation problem, because the value in the next step for the getEuler function is correct (92°). Even if I use the following code, the vizualisation alternates. Code:
euler = body.getEuler(viz.ABS_GLOBAL) euler[1] = 92.0 body.setEuler(viz.ABS_GLOBAL) Perhaps someone can help me. Sandro |
#2
|
|||
|
|||
You are using the setEuler function incorrectly, it should look like the following:
Code:
body.setEuler(euler,viz.ABS_GLOBAL) |
#3
|
|||
|
|||
Hi farshizzo
Thank you for your reply. You are right, but this was just a mistake in my post, in the real code I use it in the right way. I found out that from the getEuler command I get the following values over time when the euler[1] is below 90°. [89.999992370605469, 15.054423282822412, 180.0] [89.999992370605469, 15.284483029244234, -180.0] [89.999992370605469, 15.514467754963817, 180.0] [89.999984741210937, 15.744379632324945, -180.0] [89.999984741210937, 15.974220816530522, 180.0] So euler[1] is counting up as I wish, but euler[2] changes between 180 and -180. When I then come to euler[1] above 90° the following happens: [89.999969482421875, 89.331317543614588, -179.99996948242187] [90.000259399414063, 89.671680555074119, -179.99967956542969] [90.000267028808594, 90.014174815361827, -179.99966430664062] [-89.993125915527344, 90.358861660505966, 0.006933863740414381] [90.006790161132813, 90.705805246476245, -179.99314880371094] [-89.993240356445313, 91.055072733185696, 0.0068237865343689919] [90.006736755371094, 91.406734484200612, -179.99319458007812] [-89.993148803710938, 91.760864283827303, 0.0069220983423292637] [90.006858825683594, 92.117539573461329, -179.99307250976562] [-89.993156433105469, 92.117539573461329, 0.0069229668006300926] euler[2] has already a roundoff error and has now -179.999 or something like this. euler[2] and euler[0] now switch the "direction", if I then set the euler[1] to my angle (above 90°) then the rotation with the 3 euler angles gives different positions of the body. I hope this helps to find the problem. Sandro |
#4
|
|||
|
|||
If you are trying to modify an existing rotation, it is best to perform the changes using matrix multiplications. Manually changing a single component of an euler rotation is not very reliable, this is simply the nature of euler angles. What specific modification are you trying to perform on the rotation?
|
#5
|
|||
|
|||
Hi
The following is a small test code that should show a little bit what i like to do. You just need the attached objects from the .zip file. The "bar2" should represents a vehicle, and the "bar" should represent a arm, that is attached to the vehicle and can rotate (something like a lift arm). The vehicle should be able to "steer" and drive, so it can change its direction on the world plane. This is simulated with the key´s "f" and "g". The lift arm is controlled with "t" and "b". In the small test code the Problem occurs just with the lift arm. In my real code it occurs also for the vehicle when I try to drive around and steer. Then the vehicle changes its direction from one step to the next by 180 or 90 degrees. I hope someone can point me in the right direction, how to do this in the right way. Sandro Code:
import viz viz.go() viz.clearcolor(0.1,0.1,1) ground = viz.add('tut_ground.wrl') ANCHOR_POS= (0.5,1.8005,6) bar2 = viz.add('bar.obj',pos=ANCHOR_POS) bar = bar2.add('bar.obj') a = 0 b = 0 def mytimer(num): global a,b if viz.iskeydown('t'): a = a + 1 move() if viz.iskeydown('b'): a = a - 1 move() if viz.iskeydown('f'): b = b + 1 move() if viz.iskeydown('h'): b = b - 1 move() def move(): euler = bar.getEuler(viz.ABS_PARENT) print euler euler[1]=a bar.setEuler(euler,viz.ABS_PARENT) euler = bar2.getEuler(viz.ABS_GLOBAL) print euler euler[0]=b bar2.setEuler(euler,viz.ABS_GLOBAL) viz.callback(viz.TIMER_EVENT,mytimer) viz.starttimer(0,0.02,viz.FOREVER) |
#6
|
|||
|
|||
I modified your script to work with the built-in relative transform modes. Hopefully this should work better:
Code:
import viz viz.go() viz.clearcolor(0.1,0.1,1) ground = viz.add('tut_ground.wrl') ANCHOR_POS= (0.5,1.8005,6) bar2 = viz.add('bar.obj',pos=ANCHOR_POS) bar = bar2.add('bar.obj') MOVE_SPEED = 60 # degrees/sec def UpdateBars(): if viz.iskeydown('t'): bar.setEuler([0,MOVE_SPEED*viz.elapsed(),0],viz.REL_LOCAL) if viz.iskeydown('b'): bar.setEuler([0,-MOVE_SPEED*viz.elapsed(),0],viz.REL_LOCAL) if viz.iskeydown('f'): bar2.setEuler([MOVE_SPEED*viz.elapsed(),0,0],viz.REL_PARENT) if viz.iskeydown('h'): bar2.setEuler([-MOVE_SPEED*viz.elapsed(),0,0],viz.REL_PARENT) vizact.ontimer(0,UpdateBars) |
#7
|
|||
|
|||
Hi
Thanks for answers. The relative transform mode is a bit a problem with my application, but I tryed to do it ABS with the transform-matrix and it looks very good. The code is the following, and it seems to work also in my big script. Sandro Code:
import viz viz.go() viz.clearcolor(0.1,0.1,1) ground = viz.add('tut_ground.wrl') ANCHOR_POS= (0.5,1.8005,6) bar2 = viz.add('bar.obj',pos=ANCHOR_POS) bar = bar2.add('bar.obj') a = 0 b = 0 def mytimer(num): global a,b if viz.iskeydown('t'): a = a + 1 move() if viz.iskeydown('b'): a = a - 1 move() if viz.iskeydown('f'): b = b + 1 move() if viz.iskeydown('h'): b = b - 1 move() def move(): X = bar.getMatrix(viz.ABS_PARENT) X.setAxisAngle(1,0,0,a) bar.update(X) X = bar2.getMatrix(viz.ABS_GLOBAL) X.setAxisAngle(0,1,0,b) bar2.update(X) viz.callback(viz.TIMER_EVENT,mytimer) viz.starttimer(0,0.02,viz.FOREVER) |
|
|