Home › Forum › SOFA › Using SOFA › ForceField with Python controller
- This topic has 11 replies, 3 voices, and was last updated 6 years, 4 months ago by Hugo.
-
AuthorPosts
-
8 June 2018 at 12:05 #11176quentinBlocked
Hi everyone,
I’m trying to make a scene with a force controlled by a python controller file. I want to make a sinus force and I tried to use the ConstantForceField object but it didn’t make the thing I want. It seems that the force is constantly growing and not decrease each period of time like a sinus wave.
I would like to know if it is correct to change with a pythonController the totalForce option of the ConstantForceField component. If not, what is the error ? There is another forcefield simpler to just put a force on points ?
Thanks for your help
9 June 2018 at 09:44 #11181jnbrunetModeratorHi Quentin,
Yes, you can use a pythonController and change the value of either the
totalForce
attribute (vector 1×3) if you want that the force be split among all vertices, theforce
attribute (vector 1×3) if you want to apply the same force to all vertices, or theforces
attribute (vector nx3) to apply different forces to each vertices.Using a pythonController, simply change the attribute value of the forcefield at each
onBeginAnimationStep
event (you can find examples in the applications/plugins/SofaPython/examples directory)Hope that helps.
Jean-Nicolas12 June 2018 at 11:56 #11187quentinBlockedHi Jean-Nicolas,
Thanks for your help ! I changed the string I sent to the totalForce in a vector like that :
self.forceField.findData('totalForce').value = [0, force, 0]
I display the new totalForce on the terminal like that :
print(self.forceField.findData('totalForce').value)
I have the good value as I want with my negative sinus square (I see the force arrow s on the GUI) but the deformation doesn’t seem to follow the force signal. In fact, I have a tube with a spring in the middle and I try to compress it. I block the bottom and apply the force on the top part. The problem is that the force is a sinus and the deformation continues to increase permanently (so a line). Here you can see the force applied in the vector lines and the position of the point just under each vector.
[[0.0, -0.0, 0.0]] 1000.0 [[0.0, -21067.05423352457, 0.0]] 998.210218854 [[0.0, -81309.41177357652, 0.0]] 996.376814199 [[0.0, -172266.21253047822, 0.0]] 993.959163958 [[0.0, -281162.84414120595, 0.0]] 991.292846044 [[0.0, -392705.09831248416, 0.0]] 987.782535008 [[0.0, -491227.196924607, 0.0]] 983.855256778 [[0.0, -562892.0040131591, 0.0]] 979.023956496 [[0.0, -597634.4103943433, 0.0]] 973.678487509 [[0.0, -590574.9483385893, 0.0]] 967.601948838 [[0.0, -542705.0983124842, 0.0]] 961.047161738 [[0.0, -460748.03849369887, 0.0]] 954.060967265 [[0.0, -356214.3943757172, 0.0]] 946.75375456 [[0.0, -243785.6056242822, 0.0]] 939.283539129 [[0.0, -139251.96150630055, 0.0]] 931.704832793 [[0.0, -57294.90168751533, 0.0]] 924.099724048 [[0.0, -9425.051661410507, 0.0]] 916.501371709 [[0.0, -2365.5896056567476, 0.0]] 908.91719647 [[0.0, -37107.99598684137, 0.0]]
12 June 2018 at 16:37 #11195HugoKeymasterHi Quentin
Have you tried to use this instead:
forceToSet = self.forceField.findData('totalForce').value forceToSet[1] = force
or
self.forceField.findData('totalForce').value[1] = force
Let me know how this works
CheersHugo
12 June 2018 at 17:23 #11197quentinBlockedHi Hugo,
Thanks for your help ! I tried to directly update the data as you said. The vector is a column one therefore I can access the value like that :
print(self.forceField.findData('totalForce').value[0][1])
Nevertheless, it is impossible to edit it directly, it seems that I have to edit all the vector.
This isn’t working :
self.forceField.findData('totalForce').value[0][1] = force
This is working :
self.forceField.findData('totalForce').value = [0, force, 0]
12 June 2018 at 17:47 #11199HugoKeymasterDo you mean this is working:
self.forceField.findData('totalForce').value = [0, force, 0]
?Did you solve your problem then ?
Best
H12 June 2018 at 17:57 #11200quentinBlockedYes I mean it, I see the force arrows as before but I still have the problem of the displacement which isn’t following the force signal. The situation hasn’t changed.
14 June 2018 at 11:49 #11207quentinBlockedHi everyone,
I found in the oxygen that the
totalForce
is the sum of all the forces applied at each point : https://www.sofa-framework.org/api/master/sofa/html/classsofa_1_1component_1_1forcefield_1_1_constant_force_field.html#a7f45cdbc837c9ac22f44763806e0823fThat’s why we have the deformation which is not following the force signal. The problem is when I use the
force
attribute I have the value of the force applied on each point and not divided by the number of points. Is there another attribute that I didn’t find to apply a force which will not be summed in time to all the points (and not to each point) ?14 June 2018 at 16:33 #11208quentinBlockedTo resolve my problem, I juste have to see the value of the force really applied on each point. Is it possible to access it with the indices or an option like that ?
27 June 2018 at 17:38 #11241HugoKeymasterYou have a field “force” in the MechanicalObject summing all forces applied on your object. This can be a state vector to investigate to detect the forces applied on it.
Let me know if you solved your issue.Best,
Hugo
29 June 2018 at 16:17 #11248quentinBlockedHi @Hugo,
Thanks for the help ! The sum that you talk about, is it a temporal sum or just a sum of all the forces at the precise time ?
Thanks for the help
29 June 2018 at 16:52 #11249HugoKeymasterthe force datafield gathers all forces applied for each time step. The value of the vector is cleared at each new time step.
BestHugo
-
AuthorPosts
- You must be logged in to reply to this topic.