# Problem of Bodies rotation

Asked by yang yi on 2019-11-21

I hope to design a plane named IDGround, it can rotate with the given velocity, and it can be controlled to start, stop, change the speed and the direction in the simulation.
I used the pack.sweptPolylines2gtsSurface to establish the plane, and used the O.bodies[i].state.angVel to set the velocity. It can rotate. But the plane is combined by two triangles, so there are two bodies in the plane, and each of them rotates around the itself axis. I hope both of them rotating around a given axis. How can I change my code as follows??
Thank you very much.

Yang Yi

positionGround = [
Vector3(0,0,0),
Vector3(1,0,0),
Vector3(1,1,0),
Vector3(0,1,0)
]
Ground = pack.sweptPolylines2gtsSurface([positionGround], capStart=True, capEnd=True)
IDGround = O.bodies.append(pack.gtsSurface2Facets(Ground, color=(1,0,1)))

def myRotation():
for i in IDGround:
O.bodies[i].state.angVel=(0, 0, 1)

O.engines = [
ForceResetter(),
InsertionSortCollider([Bo1_Sphere_Aabb(), Bo1_Facet_Aabb()]),
InteractionLoop(
# handle sphere+sphere and facet+sphere collisions
[Ig2_Sphere_Sphere_ScGeom(), Ig2_Facet_Sphere_ScGeom()],
[Ip2_FrictMat_FrictMat_FrictPhys()],
[Law2_ScGeom_FrictPhys_CundallStrack()]),
NewtonIntegrator(gravity=(-9.8, 0, 0), damping=0.001, label='down'),
PyRunner(command="myRotation()",iterPeriod=400000)
# RotationEngine(rotationAxis=(0, 0, 1), angularVelocity=10.0, rotateAroundZero=True, zeroPoint=(0, 0, 0))
]

## Question information

Language:
English Edit question
Status:
Solved
For:
Assignee:
No assignee Edit question
Solved by:
Jan Stránský
Solved:
2019-11-22
Last query:
2019-11-22
2019-11-22
 Jan Stránský (honzik) said on 2019-11-21: #1

Hello,

I see 2 main options:
1) use RotationEngine
2) use a clump of facets instead of independent facets

cheers
Jan

 Chareyre (bruno-chareyre-9) said on 2019-11-21: #2

Hi, I would support 2) for the sake of performance, but there's also
3) fix myRotation() since obviously imposing rigid body motion needs to
impose 'vel' too (spin*pos), not just 'angVel'.
Bruno

Le jeu. 21 nov. 2019 12:58, yang yi <email address hidden>
a écrit :

> New question #686076 on Yade:
>
> I hope to design a plane named IDGround, it can rotate with the given
> velocity, and it can be controlled to start, stop, change the speed and the
> direction in the simulation.
> I used the pack.sweptPolylines2gtsSurface to establish the plane, and used
> the O.bodies[i].state.angVel to set the velocity. It can rotate. But the
> plane is combined by two triangles, so there are two bodies in the plane,
> and each of them rotates around the itself axis. I hope both of them
> rotating around a given axis. How can I change my code as follows??
> Thank you very much.
>
> Yang Yi
>
> positionGround = [
> Vector3(0,0,0),
> Vector3(1,0,0),
> Vector3(1,1,0),
> Vector3(0,1,0)
> ]
> Ground = pack.sweptPolylines2gtsSurface([positionGround], capStart=True,
> capEnd=True)
> IDGround = O.bodies.append(pack.gtsSurface2Facets(Ground, color=(1,0,1)))
>
> def myRotation():
> for i in IDGround:
> O.bodies[i].state.angVel=(0, 0, 1)
>
> O.engines = [
> ForceResetter(),
> InsertionSortCollider([Bo1_Sphere_Aabb(), Bo1_Facet_Aabb()]),
> InteractionLoop(
> # handle sphere+sphere and facet+sphere collisions
> [Ig2_Sphere_Sphere_ScGeom(), Ig2_Facet_Sphere_ScGeom()],
> [Ip2_FrictMat_FrictMat_FrictPhys()],
> [Law2_ScGeom_FrictPhys_CundallStrack()]),
> NewtonIntegrator(gravity=(-9.8, 0, 0), damping=0.001, label='down'),
> PyRunner(command="myRotation()",iterPeriod=400000)
> # RotationEngine(rotationAxis=(0, 0, 1), angularVelocity=10.0,
> rotateAroundZero=True, zeroPoint=(0, 0, 0))
> ]
>
>
> --
>
> _______________________________________________
> Post to : <email address hidden>
>
>
>

 Jan Stránský (honzik) said on 2019-11-21: #3

Just a note, 3) and 1) does the same, either "automatically" (1) or "manually" (3)
Jan

 yang yi (yangyizaixian) said on 2019-11-22: #4

Thanks for Jan Stránský (honzik) and Chareyre (bruno-chareyre-9) very much.
I tired the RotationEngine before using O.bodies[i].state.angVel . However, the speed I cound not change during simulation. The Code is as below:

O.engines = [
。。。。。。
RotationEngine(rotationAxis=(0, 0, 1), angularVelocity= velocity, rotateAroundZero=True, zeroPoint=(0, 0, 0))，
PyRunner(comment= "ChangeVelocity()"....)
]

But the velocity can not changed. So I tried the third way. Yestoday night, I fund the function of RotationEngine in the KinematicEngines.cpp, I understand the Chareyre's advise that the velocity should be improved during the angleVelocity. I wirte the code now, But I meet a new problem, I can not find the function of AngleAxisr(). The code of RotationEngine is

void RotationEngine::apply(const vector<Body::id_t>& ids){
if (ids.size()>0) {
const long size=ids.size();
#pragma omp parallel for schedule(static)
for(long i=0; i<size; i++){
const Body::id_t& id=ids[i];
#else
FOREACH(Body::id_t id,ids){
#endif
assert(id<(Body::id_t)scene->bodies->size());
Body* b=Body::byId(id,scene).get();
if(!b) continue;
b->state->angVel+=rotationAxis*angularVelocity;
if(rotateAroundZero){
const Vector3r l=b->state->pos-zeroPoint;
Quaternionr q(AngleAxisr(angularVelocity*scene->dt,rotationAxis));
Vector3r newPos=q*l+zeroPoint;
b->state->vel+=Vector3r(newPos-b->state->pos)/scene->dt;
}
}
} else {
LOG_WARN("The list of ids is empty! Can't move any body.");
}
}

So I need to write the function AngleAxisr().
Thank you very much!!!!

Yang Yi

 Jan Stránský (honzik) said on 2019-11-22: #5

> However, the speed I cound not change during simulation.
> But the velocity can not changed.

Why?
Please always try to be specific. Did you get an error? What error? The velocity did not change? How did you investigate it? ...
###
RotationEngine(..., label="rotEngine")
...
def myRotation():
rotEngine.angularVelocity = whatever
###

Concerning axis-angle, in Python Quaternion can be constructed directly from axis and angle:
C++: Quaternionr q(AngleAxisr(angularVelocity*scene->dt,rotationAxis));
Python: q = Quaternion(rotationAxis,angularVelocity*O.dt)

cheers
Jan

 yang yi (yangyizaixian) said on 2019-11-22: #6

Thank you very much!! Jan Stránský
Now I have two problem

(1) for using RotationEngine, I hope the following code can change the direction of the plane by the PyRunner function ChangeVelocity, but it cannot, the value of Velocity can be changed, but the plane still Rotation as the initial speed and direction.

velocity = 10
def ChangeVelocity():
global velocity
velocity = -1 * velocity

O.engines = [
ForceResetter(),
InsertionSortCollider([Bo1_Sphere_Aabb(), Bo1_Facet_Aabb()]),
InteractionLoop(
# handle sphere+sphere and facet+sphere collisions
[Ig2_Sphere_Sphere_ScGeom(), Ig2_Facet_Sphere_ScGeom()],
[Ip2_FrictMat_FrictMat_FrictPhys()],
[Law2_ScGeom_FrictPhys_CundallStrack()]),
# [Ip2_ViscElMat_ViscElMat_ViscElPhys()],
# [Law2_ScGeom_ViscElPhys_Basic()]),
NewtonIntegrator(gravity=(-9.8, 0, 0), damping=0.001, label='down'),
RotationEngine(rotationAxis=(0, 0, 1), angularVelocity=velocity, rotateAroundZero=True, zeroPoint=(0, 0, 0)),
PyRunner(command="ChangeVelocity()", iterPeriod=100000)

]

(2) The problem of transform the C++ code of RotationEngine to python, I hope I can control the rotation velocity of the plane.

def myRotation():
ZeroPos = Vector3(1, 1, 0)
rotationAxis = Vector3(0, 0, 1)
angVel = 10
for i in IDGround:
O.bodies[i].state.angVel += rotationAxis * angVel
l = O.bodies[i].state.pos - ZeroPos
q = Quaternion(AngleAxis(rotationAxis, angVel* O.dt))
# q = Quaternion(rotationAxis, angVel * O.dt)
newp = q*l + ZeroPos
O.bodies[i].state.vel += (newp - O.bodies[i].state.pos)/O.dt

O.engines = [
ForceResetter(),
InsertionSortCollider([Bo1_Sphere_Aabb(), Bo1_Facet_Aabb()]),
InteractionLoop(
# handle sphere+sphere and facet+sphere collisions
[Ig2_Sphere_Sphere_ScGeom(), Ig2_Facet_Sphere_ScGeom()],
[Ip2_FrictMat_FrictMat_FrictPhys()],
[Law2_ScGeom_FrictPhys_CundallStrack()]),
# [Ip2_ViscElMat_ViscElMat_ViscElPhys()],
# [Law2_ScGeom_ViscElPhys_Basic()]),
NewtonIntegrator(gravity=(-9.8, 0, 0), damping=0.001, label='down'),
PyRunner(command="myRotation()",iterPeriod=400000)
# RotationEngine(rotationAxis=(0, 0, 1), angularVelocity=velocity, rotateAroundZero=True, zeroPoint=(0, 0, 0)),
# PyRunner(command="ChangeVelocity()", iterPeriod=100000)
]

I can find the "AngleAxis", and the error is "name 'AngleAxis' is not defined". The above code is follow the C++ in the KinematicEngines.cpp. I don't know if the transform is correct or not.

 Jan Stránský (honzik) said on 2019-11-22: #7

1) you have to change velocity directly of RotationEngine (see my previous anwer #5). This way, you change a global velocity variable, byt RotationEngine has its copy and the change has no effect on it.

2) again see #5, should be
q = Quaternion(rotationAxis, angVel* O.dt) # without any AngleAxis stuff

cheers
Jan

 yang yi (yangyizaixian) said on 2019-11-22: #8

Thanks Jan Stránský, that solved my question.