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:
Yade Edit question
Assignee:
No assignee Edit question
Solved by:
Jan Stránský
Solved:
2019-11-22
Last query:
2019-11-22
Last reply:
2019-11-22
Jan Stránský (honzik) said : #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 : #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:
> https://answers.launchpad.net/yade/+question/686076
>
> 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))
> ]
>
>
> --
> You received this question notification because your team yade-users is
> an answer contact for Yade.
>
> _______________________________________________
> Mailing list: https://launchpad.net/~yade-users
> Post to : <email address hidden>
> Unsubscribe : https://launchpad.net/~yade-users
> More help : https://help.launchpad.net/ListHelp
>
>
>

Jan Stránský (honzik) said : #3

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

yang yi (yangyizaixian) said : #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) {
  #ifdef YADE_OPENMP
  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 : #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 : #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.

 Please help me,Thank you very much,

Best Jan Stránský (honzik) said : #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 : #8

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