# Rototraslation of a cylinder

Asked by Paolo on 2020-02-16

Hi!
I'd like do realize a counterclockwise rotating cylinder in order to spread some particles/spheres in a layer. The cylinder has to translate and rotate and so I included in the code both RotationEngine and TranslationEngine.

The problem is that during the roto-translation the pieces that constitute the cylinder rotate with respect to their centroids instead of the center of the cylinder. I saw on yade manual that it is possible to add the zeroPoint condition in the Rotatonal engine but the zeroPoint (which is the center of the cylinder) is moving due to the TranslationEngine and so not fixed.

Moreover I'd like to know if it is possible to make the cylinder restart from the initial position after some iter (i.e. the cylinder roto-translate for 10cm and then it disappear and reappear in the initial position like a cycle).

Thank you!

raggio=0.0004
rullo=O.bodies.append(geom.facetCylinder((-raggio,raggio,raggio),radius=raggio,height=0.0008,orientation=Quaternion((0,1,0),pi/2),wallMask=7,segmentsNumber=50))

O.engines=...

rotEngine = RotationEngine(ids=rullo,angularVelocity=10,rotationAxis=(1,0,0))
transEngine = TranslationEngine(ids=rullo,translationAxis=(0,1,0),velocity=vel)
O.engines = O.engines[:4]+[rotEngine+transEngine]+O.engines[4:]

## Question information

Language:
English Edit question
Status:
Solved
For:
Yade Edit question
Assignee:
No assignee Edit question
Solved by:
Jan Stránský
Solved:
2020-02-18
Last query:
2020-02-18
Last reply:
2020-02-18
 Jan Stránský (honzik) said on 2020-02-16: #1

> but the zeroPoint (which is the center of the cylinder) is moving due to the TranslationEngine and so not fixed.

you have to set new position each iteration e.g. using PyRunner

> if it is possible to make the cylinder restart from the initial position after some iter

yes. You can:
- create a new at original position (and destroy the old one)
- set appropriate state.pos of the cylinder components to match the original position
- set for one iteration velocity and angular velocity such that the cylinder moves to its original position

cheers
Jan

 Paolo (p4olo) said on 2020-02-16: #2

Hi Jan and thank you for your answer.

Just to clarify:

>you have to set new position each iteration e.g. using PyRunner

Have I to define a function that compute the next position of the center (es. transl_velocity*O.dt) which is called by the command of the pyrunner at iterPeriod=1?

>create a new at original position (and destroy the old one)

How can i destroy the old cylinder? And once i generate the new cylinder, do I have to update the translational and rotational engine in order to fit the new roller or can i simply name it as the previous one so that the engine works automaticalluy?

Thanks

 Jan Stránský (honzik) said on 2020-02-16: #3

> Have I to define a function ...

exactly

> How can i destroy the old cylinder?

for i in rullo:
O.bodies.erase(i) # [1]

> And once i generate the new cylinder, do I have to update the translational and rotational engine in order to fit the new roller or can i simply name it as the previous one so that the engine works automaticalluy?

you can name is the same, but you have to update rotEngine.ids and transEngine.ids
Depending on specific realization, you might also need to update the function computing new zeroPoint

cheers
Jan

 Paolo (p4olo) said on 2020-02-18: #5

Hi!

I succeeded in doing the rototranslation of the roller pretty well also thanks to a code I found here [1] and the erasing too, but I have trouble in generating the second roller after the deleting of the previous one. Actually I was able to write a script which generates 2 rollers at the very start of the simulation which are overlapped. The simulation makes firstly the first roller move, erases it and then the second one strarts to move. However, I'd like to generate the second one after the deleting of the firt one because I think that the final simulation could be faster if I have one cylinder at a time. Here's a draft of the code.

rullo = geom.facetCylinder((0,0,0),radius=r,height=d,orientation=Quaternion((0,1,0),pi/2),wallMask=7,segmentsNumber=50,material=Mat1)
O.bodies.append(rullo)
idsr = [r1.id for r1 in rullo]

rullo1 = geom.facetCylinder((0,0,0),radius=r,height=d,orientation=Quaternion((0,1,0),pi/2),wallMask=7,segmentsNumber=50,material=Mat1)
O.bodies.append(rullo1)
idsr1 = [r2.id for r2 in rullo1]

O.engines=[
..........

CombinedKinematicEngine(ids=idsr,label='combEngine') + TranslationEngine(translationAxis=(0,1,0),velocity=0) + RotationEngine(rotationAxis=(1,0,0), angularVelocity=0,rotateAroundZero=True,zeroPoint=(0,0,0)),

.....
]

transEngine, rotEngine = combEngine.comb[0], combEngine.comb[1]

def updateRoller():
transEngine.velocity = vel
rotEngine.angularVelocity = angVel
rotEngine.zeroPoint += Vector3(0,1,0)*vel*O.dt
if rotEngine.zeroPoint[1]>limit:
for t in range(min(idsr),max(idsr)+1):
rotEngine.zeroPoint *= 0
transEngine.velocity = 0
rotEngine.angularVelocity = 0
O.bodies.erase(t)
checker.command='step2()'

def step2():
combEngine.ids=idsr1
transEngine.velocity = vel
rotEngine.angularVelocity = angVel
rotEngine.zeroPoint += Vector3(0,1,0)*vel*O.dt

 Jan Stránský (honzik) said on 2020-02-18: #6

> but I have trouble in generating the second roller after the deleting of the previous one.

please be more specific, what have you tried and why/how it did not work

thanks
Jan

 Paolo (p4olo) said on 2020-02-18: #7

Let's suppose to define the second roller "rullo1" after deleting the previous one "rullo" as follows. After the deleting, the simulation generates 2 rollers in the position(0,0,0): one remains fixed and the other one moves correctly. I don't know why it generates 2 rollers.

def updateRoller():
transEngine.velocity = vel
rotEngine.angularVelocity = angVel
rotEngine.zeroPoint += Vector3(0,1,0)*vel*O.dt
if rotEngine.zeroPoint[1]>l3-r:
for t in range(min(idsr),max(idsr)+1):
rotEngine.zeroPoint *= 0
transEngine.velocity = 0
rotEngine.angularVelocity = 0
O.bodies.erase(t)
rullo1 = geom.facetCylinder((0,0,0),radius=r,height=d,orientation=Quaternion((0,1,0),pi/2),wallMask=7,segmentsNumber=50,material=Mat1)
O.bodies.append(rullo1)
global idsr1
idsr1 = [r2.id for r2 in rullo1]
checker.command='step2()'

def step2():
combEngine.ids=idsr1
transEngine.velocity = vel
rotEngine.angularVelocity = angVel
rotEngine.zeroPoint += Vector3(0,1,0)*vel*O.dt

 Jan Stránský (honzik) said on 2020-02-18: #8

> for t in range(min(idsr),max(idsr)+1):
> ...
> rullo1 = geom.facetCylinder(...)

are you sure you have only two cylinders? :-)
put the creating line oustide the for loop and it should work

another note, O.bodies.append returns list of IDs, so you can save some lines (and potention source of problems) as :
##
global idsr1
idsr1 = O.bodies.append(rullo1)
##

cheers
Jan

 Paolo (p4olo) said on 2020-02-18: #9

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

To post a message you must log in.