Home › Forum › SOFA › Programming with SOFA › Cloth on a table with Collision and friction
Tagged: cloth
- This topic has 14 replies, 2 voices, and was last updated 5 years, 5 months ago by Hugo.
-
AuthorPosts
-
24 May 2019 at 13:24 #13528RishabhBlocked
Hello,
I am trying to simulate a cloth on a rigid surface (table).
Requirements:
* Friction between the cloth and the table
* Collision between the cloth and the tableCurrent stage:
* There is friction and collision between the rigid block and the table as taken from the examples/constraints/friction example. But this is also not perfect because of the scarcity of points on the surface.
* No friction or collision available between the cloth and the surfaceVideo: https://drive.google.com/file/d/1mz5aUf-AwYm_KikZyIyNMkyIGXVy3N0o/view?usp=sharing
Scene file: https://gist.github.com/jangirrishabh/41e82756da90b1b10a985a7df1a32604
The final aim to simulate a normal behavior of how a cloth should be on a rigid table. Kindly help.
cheers,
Rishabh
27 May 2019 at 19:23 #13536HugoKeymasterHi @jangirrishabh ,
Here is a simplified version of your scene. There was an issue with the collision mesh of the cloth. I suspect the Gmsh format doing something weird here but I am not 100% sure.
I also increase the distance of contact which was too small. Be also careful with the timestep, not chosing it too large for stability issue.
Hoping this helps:
<Node name="root" dt="0.05" gravity="0 -9.810 0"> <VisualStyle displayFlags="hideBehaviorModels showCollisionModels hideMappings hideForceFields showVisualModels showInteractionForceFields" /> <RequiredPlugin name='SofaMiscCollision'/> <FreeMotionAnimationLoop solveVelocityConstraintFirst="0" /> <LCPConstraintSolver maxIt="1000" tolerance="1e-6" initial_guess="false" build_lcp="true" multi_grid="false" printLog="0" mu="0.9"/> <CollisionPipeline depth="15" verbose="0" draw="0" /> <BruteForceDetection name="N2" /> <LocalMinDistance name="Proximity" alarmDistance="03" contactDistance="01" useLMDFilters="0" /> <CollisionResponse name="Response" response="FrictionContact" /> <MeshGmshLoader name="loader" filename="mesh/square3.msh" createSubelements="true" rotation="90 0 0" scale="100" /> <Node name="cloth"> <EulerImplicitSolver name="cg_odesolver" printLog="false" rayleighStiffness="0.1" rayleighMass="0.1" /> <CGLinearSolver iterations="25" name="linear solver" tolerance="1.0e-9" threshold="1.0e-9" /> <TriangleSetTopologyContainer name="algo" src="@../loader"/> <TriangleSetGeometryAlgorithms name="algo" template="Vec3d" recomputeTrianglesOrientation="1"/> <MechanicalObject name='cloth' src="@../loader" template="Vec3d" /> <DiagonalMass massDensity="0.01" /> <FixedConstraint indices="1" /> <TriangularFEMForceField name="FEM" youngModulus="1000" template="Vec3d" poissonRatio="0.1" method="large" /> <TriangularBendingSprings name="FEM-Bend" stiffness="10" template="Vec3d" damping="1.0" /> <!-- <TriangleSet /> --> <!-- <Triangle name="models" /> <Line /> <Point /> --> <UncoupledConstraintCorrection compliance="100"/> <Node name="TriangularSurface"> <TriangleSetTopologyContainer name="Container" /> <TriangleSetTopologyModifier name="Modifier" /> <Tetra2TriangleTopologicalMapping input="@../topo" output="@Container" /> <Triangle name="models" /> <Line /> <Point /> </Node> <Node name="clothVisual"> <OglModel name="Visual" src="@../loader" color="red" template="ExtVec3d"/> <IdentityMapping input="@.." output="@Visual" /> </Node> <Node name="Edge Mesh"> <EdgeSetTopologyContainer name="Container" /> <EdgeSetTopologyModifier name="Modifier" /> <EdgeSetGeometryAlgorithms template="Vec3d" name="GeomAlgo" drawEdges="1" /> <EdgeSetTopologyAlgorithms template="Vec3d" name="TopoAlgo" /> <Triangle2EdgeTopologicalMapping name="Mapping" input="@../Container" output="@Container" /> <MeshSpringForceField template="Vec3d" stiffness="300" damping="1.0" /> </Node> </Node> <Node name="CUBE"> <EulerImplicitSolver name="cg_odesolver" printLog="false" rayleighStiffness="0.1" rayleighMass="0.1" /> <CGLinearSolver iterations="25" name="linear solver" tolerance="1.0e-9" threshold="1.0e-9" /> <MechanicalObject template="Rigid3d" scale="2.0" translation="-10 10 -40" /> <UniformMass totalMass="10.0" /> <UncoupledConstraintCorrection compliance="0.1"/> <Node name="Visu"> <OglModel name="Visual" fileMesh="mesh/smCube27.obj" color="0.0 0.5 0.5 1.0" scale="2.0" /> <RigidMapping input="@.." output="@Visual" /> </Node> <Node name="Surf2"> <MeshObjLoader name="loader" filename="mesh/smCube27.obj" triangulate="true" /> <MeshTopology src="@loader"/> <MechanicalObject src="@loader" scale="2.0" /> <Triangle/> <Line/> <Point/> <RigidMapping /> </Node> </Node> <Node name="Floor"> <MeshObjLoader name="loader" filename="mesh/floorFlat.obj" triangulate="true" scale="10" translation="50 -10 50" /> <MeshTopology src="@loader" /> <MechanicalObject src="@loader" name="DOFs" template="Vec3d" /> <Triangle simulated="0" moving="0" contactFriction="100"/> <Line simulated="0" moving="0" contactFriction="100"/> <Point simulated="0" moving="0" contactFriction="100"/> <OglModel name="FloorV" /> </Node> </Node>
Best
Hugo
28 May 2019 at 14:45 #13543RishabhBlockedHi @Hugo,
Thank you very much, I am currently able to achieve all the above required functionalities with your inputs !
One of my only concern is the speed of simulation, adding friction has slowed it down quite a bit, could you suggest ways to speed up the simulation (like without rendering is one solution that I use), I have also tried to decrease the collision pipeline depth hoping the speed improves, thoughts?
There we just a few minor typos in the above script, embedding the working slightly modified script here for reference of others,
<Node name="root" dt="0.05" gravity="0 -9.810 0"> <VisualStyle displayFlags="hideBehaviorModels hideCollisionModels hideMappings hideForceFields showVisualModels hideInteractionForceFields" /> <RequiredPlugin name='SofaMiscCollision'/> <FreeMotionAnimationLoop solveVelocityConstraintFirst="0" /> <LCPConstraintSolver maxIt="1000" tolerance="1e-6" initial_guess="false" build_lcp="true" multi_grid="false" printLog="0" mu="1.9"/> <CollisionPipeline depth="6" verbose="0" draw="0" /> <BruteForceDetection name="N2" /> <LocalMinDistance name="Proximity" alarmDistance="03" contactDistance="01" useLMDFilters="0" /> <CollisionResponse name="Response" response="FrictionContact" /> <Node name="cloth"> <EulerImplicitSolver name="cg_odesolver" printLog="false" rayleighStiffness="0.1" rayleighMass="0.1" /> <CGLinearSolver iterations="25" name="linear solver" tolerance="1.0e-9" threshold="1.0e-9" /> <MeshGmshLoader name="loader" filename="mesh/square3.msh" createSubelements="true" rotation="90 0 0" scale="100" /> <TriangleSetTopologyContainer name="topo" src="@loader"/> <TriangleSetGeometryAlgorithms name="algo" template="Vec3d" recomputeTrianglesOrientation="1"/> <MechanicalObject name='clothMech' src="@loader" template="Vec3d" /> <DiagonalMass massDensity="0.01" /> <!-- <FixedConstraint indices="1" /> --> <TriangularFEMForceField name="FEM" youngModulus="1000" template="Vec3d" poissonRatio="0.1" method="large" /> <TriangularBendingSprings name="FEM-Bend" stiffness="1" template="Vec3d" damping="2.0" /> <UncoupledConstraintCorrection compliance="100"/> <Node name="TriangularSurface"> <TriangleSetTopologyContainer name="Container" /> <TriangleSetTopologyModifier name="Modifier" /> <Tetra2TriangleTopologicalMapping input="@../topo" output="@Container" /> <Triangle name="models" /> <Line /> <Point /> </Node> <Node name="clothVisual"> <OglModel name="Visual" src="@../loader" color="red" template="ExtVec3f"/> <IdentityMapping input="@.." output="@Visual" /> </Node> <Node name="Edge Mesh"> <EdgeSetTopologyContainer name="Container" /> <EdgeSetTopologyModifier name="Modifier" /> <EdgeSetGeometryAlgorithms template="Vec3d" name="GeomAlgo" drawEdges="1" /> <EdgeSetTopologyAlgorithms template="Vec3d" name="TopoAlgo" /> <Triangle2EdgeTopologicalMapping name="Mapping" input="@../topo" output="@Container" /> <MeshSpringForceField template="Vec3d" stiffness="10" damping="1.0" /> </Node> </Node> <Node name="Floor"> <MeshObjLoader name="loader" filename="mesh/floorFlat.obj" triangulate="true" scale="10" translation="50 -10 50" /> <MeshTopology src="@loader" /> <MechanicalObject src="@loader" name="DOFs" template="Vec3d" /> <Triangle simulated="0" moving="0" contactFriction="100"/> <Line simulated="0" moving="0" contactFriction="100"/> <Point simulated="0" moving="0" contactFriction="100"/> <OglModel name="FloorV" /> </Node> </Node>
Thanks! Rishabh
28 May 2019 at 15:36 #13546HugoKeymasterHi @jangirrishabh ,
I am glad it helped.
The typos are actually not typos but just due to the fact that I am working with the master branch of SOFA (which evolved since our last release).Regarding the ways to accelerate your simulation here are some clues.
From a numerical / physical point of view, you could use a coarser mesh for the collision mesh of the cloth (and keep the current mesh for the mechanics).
Other wise you are already using quite simple/optimizied approach (diagonal mass, iterative solver). Could you just explain the reason why you need to have an additional stiffness model on the boarder of the cloth? (MeshSpringForceField)Finally, a last step would be to go for GPU (see SofaCUDA plugin) or multi-CPU (see the Multithreading plugin) approach. Note that a indie dev is currently working on multithreaded collisions. I could connect you if needed.
Best
Hugo
28 May 2019 at 16:23 #13548RishabhBlockedHi @Hugo, thank you for your prompt reply
Oh okay good, I’m still on branch 17.06, I have some python issues with the master branch.
Using a coarser mesh for collision sounds like a nice idea, i’ll try that soon thanks.
The additional stiffness in the borders was required because of the unwanted stretching of the cloth when gripped at a single point for manipulation (gripped at vertex). Do you think that slows down the simulation? I did not find any significant change in the speed with addition of this.
A question, could you please explain me the difference between
<LocalMinDistance name="Proximity" alarmDistance="03" contactDistance="01" useLMDFilters="0" />
and
<MinProximityIntersection name="Proximitty" alarmDistance="3.0" contactDistance="1.0" />
Yes! I saw the CUDA plugin but haven’t tried it yet, it would be lovely if that could work, i’ll let you know for sure. For the indie dev, it would rather be better that I stick to stable branches as the simulation is a tool but my main project drifts towards learning, so thanks anyway !
Cheers,
Rishabh28 May 2019 at 16:38 #13549RishabhBlockedHere is a picture of what I mean by the unwanted stretching of the border when gripped
Link: https://ibb.co/5LFTkCV
28 May 2019 at 17:56 #13551HugoKeymasterHi @jangirrishabh ,
My question about the boarder was just to understand your purpose. This will not have a strong impact on perf. Thanks for the screenshot.
I am no expert of these LocalMinDistance and MinProximityIntersection.
What I know is that these are classes proposing methods to compute collision detection using a set of two primitives. The difference of LocalMinDistance seems to be that it is specific for constraint-based approaches.Hugo
29 May 2019 at 12:37 #13553RishabhBlockedHi @hugo,
Okay thank you, the collision detection is causing a little problems in the main problem. I will state a small part of my setup here and I request your help in that too
Task: So I have a ball which acts as a gripper which I am manipulating through keyboard. Using the code from the examples this ball is attached (by VectorSpringForceField) to an input object whose position is controlled by the keyboard.py. The ball and the floor have a collision by using (MinProximityIntersection) but the collision does not work with LocalMinDistance. which is not a huge problem so it’s okay.
Problem:
1. The main problem (as you can see in the video) is that the ball obeys the collision, but the input object does not, they are connected by a VectorSpringForceField. How can I manipulate the ball naturally with collisions?Video: https://drive.google.com/file/d/1pTaZBkkXM28gGZgSZEdamZAfdYbvmYiX/view?usp=sharing
In the video I am first trying to move the ball (red) down and then up again. It collides with the floor and stays there, but it takes multiple “UP” key presses to get the ball going up again, this is because the DOFs object does not obey collisions and goes down anyway.
Scene File: https://gist.github.com/jangirrishabh/3ec355d28e7d01bd9d36f52afa632026
KeyboardControlFile: Attached in the gist7 June 2019 at 14:36 #13594HugoKeymasterHi @jangirrishabh ,
Are you sure the github version is up to date ?
I don’t have any green ball and the red one is not moving.Hugo
7 June 2019 at 15:01 #13595RishabhBlockedHi @hugo,
I just checked the script, it does work on v17.06 I can confirm.
The green ball (input/DOFs) is indeed “activated” in the code, I’m not sure why you can’t see it, sofa version problem maybe.
And to move the red ball use the keyboard.py script attached in the same github gist link. It so happens that sometimes it does not move at the start so you have to reset the scene again and/or click on the GUI screen and it starts working !
I do not have the v18 right now, cause I remember having troubles with the SofaPython plugin in that version (not being able to move the ball !, or even the examples provided were not really working). In any case please let me know if I should try it out on the latest version as well and report.
Thanks,
Rishabh11 June 2019 at 18:54 #13624HugoKeymasterWoaw, you’re on the v17.06, it starts being a bit outdated. Even if your issues are not directly linked to this, I advise you to update your SOFA version soon.
To fix your issue, you can use the following script:
import Sofa class KeyboardControl(Sofa.PythonScriptController): # called once graph is created, to init some stuff... def initGraph(self,node): print 'initGraph called (python side)' self.MechanicalState = node.getObject('DOFs') gravity = node.findData('gravity').value print gravity self.rootNode = node.getRoot() #self.clothMesh = self.rootNode.getChild('SquareGravity') self.ballMesh = self.rootNode.getChild('ball') self.node = node # print self.ballMesh.getObject('ballState').scale return 0 # key and mouse events; use this to add some user interaction to your scripts def onKeyPressed(self,k): # free_position is a scalar array : [tx,ty,tz,rx,ry,rz,rw] free_position=self.MechanicalState.position print free_position # translation speed speed = 1 # UP key : front if ord(k)==19: self.rootNode.reset() # DOWN key : rear if ord(k)==21: self.rootNode.cleanup() # LEFT key : left if ord(k)==23: free_position[0][1]-=speed print free_position self.MechanicalState.findData('position').value=free_position # RIGHT key : right if ord(k)==22: free_position[0][1]+=speed print free_position self.MechanicalState.findData('position').value=free_position # PAGEUP key : up if ord(k)==18: free_position[0][0]-=speed print free_position self.MechanicalState.findData('position').value=free_position # PAGEDN key : down if ord(k)==20: free_position[0][0]+=speed print free_position self.MechanicalState.findData('position').value=free_position print self.ballMesh.getObject('ballState').position, self.MechanicalState.position return 0
I just now access the position and not the free position (the free position is a temporary position used in the FreeAnimationLoop when solving the constrained system with Lagrange multipliers).
Let me know it works.
Best wishes,Hugo
12 June 2019 at 15:33 #13639RishabhBlockedHello @Hugo,
Thank you for your input, now the reference model is also moving. This is not what the problem was, but this really helps me to explain the problem better to you ! Let me use a video for explaining the problem,
Video: https://drive.google.com/file/d/1q2IwcQpYk8ZpJ3rk0Mo-MoH7QGQfzCkf/view?usp=sharing
Now here the red ball (which is attached to the blue ball through vectorSpringField) has collision, and it stops when an obstacle comes, but for the blue ball I can not put explicit sphere collision model (virtual object) and thus the blue ball keeps moving downwards. Thus my guess is that I need a kind of two-way constraint/springfield between these balls for achieving a good behavior.
Please note that my goal is solely to control motion of the red ball (under gravity) through the keyboard. Kindly help with your inputs
I had to make a little change for the red ball to follow the blue ball i.e. update the free_position of the Mechanical object as well:
if ord(k)==19: self.rootNode.reset() # DOWN key : rear if ord(k)==21: self.rootNode.cleanup() # LEFT key : left if ord(k)==23: free_position[0][1]-=speed self.MechanicalState.findData('position').value=free_position self.MechanicalState.free_position=free_position # RIGHT key : right if ord(k)==22: free_position[0][1]+=speed self.MechanicalState.findData('position').value=free_position self.MechanicalState.free_position=free_position # PAGEUP key : up if ord(k)==18: free_position[0][0]-=speed self.MechanicalState.findData('position').value=free_position self.MechanicalState.free_position=free_position # PAGEDN key : down if ord(k)==20: free_position[0][0]+=speed self.MechanicalState.findData('position').value=free_position self.MechanicalState.free_position=free_position return 0
Thank you,
Rishabh12 June 2019 at 15:43 #13640HugoKeymasterThe little change you had to do might come from the difference of SOFA version.
Just a short question, is your gist scene file up-to-date?
Hugo
12 June 2019 at 16:33 #13641RishabhBlockedHi @Hugo,
I believe so, but to not keep any margin of error, let me just post this new git file for you 🙂
Gist files link: https://gist.github.com/jangirrishabh/ce96d4208d6be4e9cbaddf69870ef50f
Both files included here, they should work without any changes
Yes the version might be the culprit here, cause the red ball does not move if I do not update the free_position of the blue ball !
Merci,
Rishabh19 June 2019 at 18:31 #13785HugoKeymasterRegarding the blue ball not following, here is the explanation. You are controlling the blue ball, which has no collision model. The red ball has a collision model therefore, when a collision occurs, the ball is stuck due to collision. Since both objects are only related by springs, even if the blue ball pulls on the red one, collision forces the red ball to remain in collision on the floor.
Does it answer your question?
bestHugo
-
AuthorPosts
- You must be logged in to reply to this topic.