torque

Asked by ytang

Hi All,

I want to get the torque of a body.

I use the following code to get the torque as well as the force.
#####################
def coon():

 friction_force_cal0 = sum(O.forces.f(b)[0] for b in cylinderIDS)
 friction_force_cal1 = sum(O.forces.f(b)[1] for b in cylinderIDS)
 friction_force_cal2 = sum(O.forces.f(b)[2] for b in cylinderIDS)
 #friction_force_cal = sum(O.forces.f(b) for b in cylinderIDS)

 #torque_cal = sum(O.forces.t(b) for b in cylinderIDS)
 torque_cal0 = sum(O.forces.t(b)[0] for b in cylinderIDS)
 torque_cal1 = sum(O.forces.t(b)[1] for b in cylinderIDS)
 torque_cal2 = sum(O.forces.t(b)[2] for b in cylinderIDS)

 f_0=utils.sumForces(ids=cylinderIDS,direction =(1,0,0))
 f_1=utils.sumForces(ids=cylinderIDS,direction =(0,1,0))
 f_2=utils.sumForces(ids=cylinderIDS,direction =(0,0,1))
 torque_0 = utils.sumTorques(ids=cylinderIDS,axis = (1,0,0),axisPt = (0.2,0,0))
 torque_1 = utils.sumTorques(ids=cylinderIDS,axis = (0,1,0),axisPt = (0,0.2,0))
 torque_2 = utils.sumTorques(ids=cylinderIDS,axis = (0,0,1),axisPt = (0,0,0.2))
 plot.addData(f1 =f_0,f2 = f_1,f3 = f_2, friction1 = friction_force_cal0,
  friction2 = friction_force_cal1, friction3 = friction_force_cal2,
  torque1 = torque_cal0, torque2 = torque_cal1, torque3 = torque_cal2,
  t1 = torque_0, t2 = torque_1,t3 = torque_2,unbalanced=unbalancedForce(),i=O.iter)

 plot.saveDataTxt('alldata.txt')

#######################
the results show that f1 = friction1, f2 = friction2, f3 = friction3. this testify the above code for forces.
while the code for torque don't give me the expeted results. (I'm thinking the t1 should be equal to torque1.)

I found that t1 = -t2.

I don't know which one is correct for the torque.
or because of the axisPt so the torque is different.

Question information

Language:
English Edit question
Status:
Solved
For:
Yade Edit question
Assignee:
No assignee Edit question
Solved by:
Jan Stránský
Solved:
Last query:
Last reply:
Revision history for this message
Jérôme Duriez (jduriez) said :
#1

I'm not really familiar to sumTorques() (or your code), but it seems strange to me to compare torques that are computed in different points.

Revision history for this message
Jan Stránský (honzik) said :
#2

> friction_force_cal = sum(O.forces.f(b) for b in cylinderIDS)
> torque_cal = sum(O.forces.t(b) for b in cylinderIDS)

python sum takes an initial value (default is 0, but does not work with vectors), so you can do:
###
friction_force_cal = sum((O.forces.f(b) for b in cylinderIDS), Vector3.Zero)
torque_cal = sum((O.forces.t(b) for b in cylinderIDS), Vector3.Zero)
###

if you sum torques "manually", do not forget to take into account forces on bodies, otherwise it is different computation than utils.sumTorques [1]

cheers
Jan

[1] https://gitlab.com/yade-dev/trunk/-/blob/master/py/_utils.cpp#L207

Revision history for this message
ytang (ytang116) said :
#3

Hi Jérôme and Jan,
sorry for the late reply.

for the command used in my code.
for instance:
###########
(1)torque_cal0 = sum(O.forces.t(b)[0] for b in cylinderIDS)
(2)torque_0 = utils.sumTorques(ids=cylinderIDS,axis = (1,0,0),axisPt = (0.2,0,0))
#########
as we all know, torque = force*(cross dot) length. so for command(1) we can get the torque, but the definition didn't mention where is the action point------so what is the meaning of this command in YADE?
as for (2), my object is a cylinder, if I want to get the torque generated from the object, which is result from the contact force * the radius of the cylinder. so I can't use command (2) also?

best,
Yong

Revision history for this message
Jan Stránský (honzik) said :
#4

> as we all know, torque = force*(cross dot) length. so for command(1) we can get the torque, but the definition didn't mention where is the action point------so what is the meaning of this command in YADE?

for command (1), you get sum of "plain" torques applied to bodies. It is something different than utils.sumTorques, but may have some use case..

If you want to sum "total" torques "manually", do the same as utils.sumTorques [1]:
torque = sum(( O.forces.t(b) + (O.bodies[b].state.pos-actionPoint).cross(O.forces.f(b)) for b in cylinderIDS), Vector3.Zero)
of not one line:
###
ret = Vector3.Zero
for i in cylinderIDS:
   b = O.bodies[i]
   p = b.state.pos
   r = p - actionPoint
   t = O.forces.t(i)
   f = O.forces.f(i)
   ret += t + r.cross(f)
###

cheers
Jan

Revision history for this message
ytang (ytang116) said :
#5

Hi Jan,

why do we need to use this: ret += t + r.cross(f)?
why not we use ret += r.cross(f)?

thanks
Yong

Revision history for this message
Jan Stránský (honzik) said :
#6

> why do we need

well, you don't need :-)
you need to use it to get the same result as utils.sumTorques, which is physically the total torque with respect to a given point from individual torques and forces applied to the bodies.

> why not we use ret += r.cross(f)?

because (obviously) you would get different result. As sum(plain torques), discussed on previous answers, also sum(torques only from forces) probably may be useful, but it is not what you are asking.

Total torque has two contributions:
- torques directly applied to bodies, i.e. "t"
- forces applied to bodies and their "excentricity", i.e. "r.cross(f)"

To get correct results, you need both (even sometimes one of the contributions may be negligible compared to the other, it is not good idea to depend on that fact)

cheers
Jan

Revision history for this message
Jérôme Duriez (jduriez) said :
#7

Going back to #3, I see O.forces.t as referring to the (resultant) torque computed at state.pos (center of mass of the Body)

Revision history for this message
ytang (ytang116) said :
#8

hi Jan,

thank you very much!

I forgot the part that the torque directly applied to the bodies.

hi Jérôme,

if I remember correctly, for the object created by the facets it doesn't have the mass by default. but we can assign the mass to that object.
generally speaking, can we say centroid of the body instead of the center of mass of the body?

Revision history for this message
Jan Stránský (honzik) said :
#9

> generally speaking, can we say centroid of the body instead of the center of mass of the body?

not really in general. Especially in the case of facets, where b.state.pos "by default" is NOT a center of mass (or centroid), but center if inscribed circle [1]

cheers
Jan

[1] https://gitlab.com/yade-dev/trunk/-/blob/master/py/utils.py#L267

Revision history for this message
ytang (ytang116) said :
#10

Hi Jan,

let me explain more clearly,
(1) for O.forces.t, the torque we get from this command, the action point is the center of the inscribed circle of that facet. which means the length in the torque equation (torque = force.cross*length) is the distance between the contact point where the contact force happens and the center of the inscribed circle of that facet.

(2) for this command: utils.sumTorques----- we can set the axis Point by ourselves at anywhere. (whether the action point is the center of the inscribed center of the facet or point at the center of the cylinder)

If I want to calculate the torque for a cylinder, it seems these two methods don't work. because in my opinion, the action point for each contact force isn't the same. the action length for each contact force is the radius of the cylinder.

I don't know whether my opinion is correct or not, you can correct me if I'm wrong.

thanks
Yong

Revision history for this message
Best Jan Stránský (honzik) said :
#11

(1) correct (more or less :-)
you need a vector for cross product, not just a length.
the branch vector = contactPoint - pos
torque = branch.cross(force), which is opposite to force.cross(branch)

(2)
TLTR: have a look at a basic materials for mechanics concerning forces, moments, sums, equlibrium...

I did not get the meaning correctly, but I think I got the confusion.

All this is about force and moment (non)equilibrium.
Consider a rigid body.

Consider a torque applied to the body. From the point of view of force and moment (non)equilibrium, it does not matter where it acts, you can shift it to any point with the same effect (the equilibrium / amount of non-equilibrium remains the same).

Consider a force applied to the body. From the point of view of force and moment (non)equilibrium, you can shift it only across its action line to have the same effect. You can shift it to any point, but then you have to adjust the torque at this point = branch.cross(force) to preserve the equilibrium / amount of non-equilibrium the same.

You can do this with multiple torques and forces, e.g. to get one sum force and torque with respect to a special point.
You can do this multiple times, i.e. shift the force and then shift the new force-torque couple again.

For the case of one single body, you have multiple interactions, at each contact point you may have torque and force.
For easier manipulation, all these forces and torques are expressed with one force and one torque with respect to b.state.pos.
(this is the value stored in O.forces)

For multiple bodies, you can:
- shift torques and forces w.r.t b.state.pos (from O.forces) to the special point
- shift torques and forces from individual interactions to the special point
the result is the same

I suggest to experiment with a few (e.g. 3) bodies to get some feeling about it.

cheers
Jan

Revision history for this message
ytang (ytang116) said :
#12

Hi Jan,

thanks!

Revision history for this message
ytang (ytang116) said :
#13

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