6 October 2020 at 16 h 43 min #17299
I am new to SOFA. I am using it to model soft robot, I am trying to model one
part of the robotic arm which should expand and bend depending on the pressure
applied on the inner walls of the cylinder. There are 6 such cylinders.
I am using the code from tutorial on PneunetGripper to modify to my need. I want
to restrict the radial expansion of the cylinders by using stiff wire wounded
around it (similar to “tie” constraint in Abaqu). However the wire expands with the cylinder and at some points the
elastic cylinder penetrates through the wire which is not desirable. I am new
to Python as well so your help will be highly appreciated.
Shan6 October 2020 at 16 h 54 min #17300
Thank you for your question and welcome on the SOFA forum.
I think you could apply a PartialFixedConstraint (defining in which direction you would like to restrict the motion) in your cylinder node.
Hugo6 October 2020 at 17 h 07 min #17302
Thanks. I will update you if I am able to resolve the issue with your suggestion.6 October 2020 at 17 h 15 min #17303DuriezParticipant
An other way (more complex but very elegant) is to have a uniform mesh of your cylinder (typically with hexahedrons / quads on surface) and then to prevent any radial expansion of your mesh, you “rigidify” each circle (each set of points of the mesh that are on the surface of the cavity and belong to the same plane perpendicular to the cylinder).
If each of these circle is now a new rigid object, the cylinder can expand in length and can bend but the radial expansion is impossible.
For the “rigidification”, the procedure is explained in the Tripod tutorial..
Christian7 October 2020 at 11 h 29 min #17323
Thanks for the suggestion. I will look into the tutorial example of Tripod to see how to implement “rigidification”. Hope to get back to you with some progress.
Shan10 October 2020 at 21 h 35 min #17354
I looked at Tripod tutorial and also looked at the following example
However I have questions regarding “frames” and “groupIndices”. Could you please explain what do they mean in terms of the mesh. I looked at few topics on rigidification and it seems to me that it has to do with BoxROI. Since I am an amateur in python so I couldn’t completely understand the code so please pardon my lack of knowledge of python. I am unclear about how to rigidify the surface mesh elements of the the outer boundary of the cylindrical structure.
In short how can I obtain frames and indices from the meshed structure.
Shantanu.12 October 2020 at 17 h 03 min #17383
I have been trying to work with tripod tutorial example to rigidify outer boundary of the cylindrical actuator I mentioned earlier. However I am stuck at extracting the “groupIndices” and “frame”. I would be highly obliged if you could help me out here. The code I implemented is as follows:
import Sofa import os #from stlib.visuals import ShowGrid from stlib.scene import MainHeader from stlib.physics.deformable import ElasticMaterialObject #from stlib.physics.constraint import FixedBox from stlib.physics.mixedmaterial import Rigidify from splib.objectmodel import setData def createScene(rootNode): #Another way to add gravity with MainHeader MainHeader(rootNode, gravity=[0.0,0.0,-9810.0]) #MainHeader(rootNode, plugins=["SofaSparseSolver"]) rootNode.createObject('VisualStyle', displayFlags='showForceFields') rootNode.createObject('RequiredPlugin', name='soft', pluginName='SoftRobots') rootNode.createObject('RequiredPlugin', name='SofaPython', pluginName='SofaPython') rootNode.createObject('PythonScriptController', filename="pythonControllers/fingerController.py", classname="controller") rootNode.createObject('FreeMotionAnimationLoop') rootNode.createObject('GenericConstraintSolver', tolerance="1e-12", maxIterations="10000") # Create Actuator mechanical model finger = rootNode.createChild('finger') finger.createObject('MeshVTKLoader', name='loader', filename='data/mesh/TestActuator') finger.createObject('Mesh', src='@loader', name='container') finger.createObject('MechanicalObject', name='tetras', template='Vec3d',showObject='true', showObjectScale='1') #finger.createObject('SubsetMultiMapping', template='Vec3d', indices='1 2 3 100') finger.createObject('TetrahedronFEMForceField', template='Vec3d', name='FEM', method='large', poissonRatio='0.4', youngModulus='1500', drawAsEdges="true") finger.createObject('UniformMass', totalMass='0.0008') finger.createObject('EulerImplicit', name='odesolver', rayleighStiffness='0.1', rayleighMass='0.1') finger.createObject('SparseLDLSolver', name='directSolver') #finger.createObject('CGLinearSolver', name='Solver') # tracking Mesh Nodes 1 2 5 6 8 10 50 55 60 100 tracking = finger.createChild('tracking') tracking.createObject('MechanicalObject', showObject='true', showObjectScale='5') tracking.createObject('SubsetMapping', indices='1 2 5 6 8 10 50 55 60 100') # FixedBox constraint at the bottom of actuator finger.createObject('BoxROI', name='boxROI', box='-10.5 -10.5 -4.5 10.5 10.5 -2', drawBoxes='true', drawSize='0.1') finger.createObject('RestShapeSpringsForceField', points='@boxROI.indices', stiffness='1e12', angularStiffness='1e12') finger.createObject('LinearSolverConstraintCorrection', solverName='directSolver') # FixedBox constraint on top of actuator finger.createObject('BoxROI', name='boxROI1', box='-10.5 -10.5 82.5 10.5 10.5 86', drawBoxes='true', drawSize='0.1') finger.createObject('RestShapeSpringsForceField', points='@boxROI1.indices', stiffness='1e12', angularStiffness='1e12') finger.createObject('LinearSolverConstraintCorrection', solverName='directSolver') # Cavity of elastic cylinder (Actuator) cavity = rootNode.finger.createChild('cavity') cavity.createObject('MeshVTKLoader', name='loader2', filename='data/mesh/TestCavity') cavity.createObject('Mesh', src='@loader2', name='cavityMesh') cavity.createObject('MechanicalObject', name='cavity', showObject='true', showObjectScale='1') cavity.createObject('SurfacePressureConstraint', name="SurfacePressureConstraint", template='Vec3d', value="0.0001", valueType="pressure") cavity.createObject('BarycentricMapping', name='mapping', mapForces='false', mapMasses='false')
The meshed geometry is in this link
Shan12 October 2020 at 17 h 12 min #17387
Also I have another question regarding the rigidification, what is the need for creating a simulationNode as given one of the topics in forum.
simulationNode = rootNode.createChild(“Simulation”)
Shan21 October 2020 at 13 h 19 min #17435
I would be obliged if someone could advise me on the above mentioned query.
Shan26 October 2020 at 17 h 05 min #17448
I requested access to your mesh to test the scene.
Regarding your last question: the way the scene is created here is a bit contra-intuitive. First, all sub-nodes are created. Finally they are added in the simulation (as child node of the root node). This root node is the starting point of the simulation, and this is where the solvers (integration scheme and linear solver) are defined in this case.
Does this help?
Hugo26 October 2020 at 17 h 06 min #17449
To understand how a rigidification works, you can also check the example: examples/Components/animationloop/MechanicalMatrixMapper.pyscn
Hugo26 October 2020 at 17 h 28 min #17450
Thanks for the reply. I granted you access to google drive, please check if you can access it.
Regarding the query about rigidification, I did go through the example you mentioned. However I am a bit confused regarding the arguments “indices” and “frames” as I am not sure how to extract it from mesh. The part I want to make rigid is the outer wall of the column so that it does not expand radially though it can still expand axially and also can bend.
I understand you guys must be busy with the upcoming events on SOFA training in November, though it would be really helpful if you could explain the functions in Python. I have gone through https://www.sofa-framework.org/api/master/sofa/html/index.html to understand the functions and classes used in SOFA Python, but its not really clear to me.
Looking forward to see you for the training session.
Shan30 October 2020 at 13 h 22 min #17479
Thank you for granting the access. I am able to run your scene.
The data “indices” means the indices of the degrees of freedom (nodes) of your deformable object which will be affected by the rigidification.
The data “frames” corresponds to a list containing the quaternion (position + orientation) of all rigid frames: [[rx,ry,rz], [qx,qy,qz,w]]
Let me know it this clarifies your point.
Regarding the global understanding of SOFA, do you have some more specific questions so that I can answer accurately?
- You must be logged in to reply to this topic.