diff --git a/README.md b/README.md index 63725184..ee615b6f 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,8 @@ Overview An open-source plugin, designed to be compatible with the Sofa framework, facilitates the simulation of 1D objects. -Specifically, it caters to the modeling of both rigid and flexible 1D entities, like rods, wires or needles, using the Cosserat beam theory. -In this context, we have outlined a range of potential applications for this plugin. If you wish to explore its functionality, you have the flexibility to -construct scenes using Python or XML, or you can take it a step further by developing new C++ components. +Specifically, it caters to the modeling of both rigid and flexible 1D entities, like rods, wires or needles, using the Cosserat beam theory. +In this context, we have outlined a range of potential applications for this plugin. If you wish to explore its functionality, you have the flexibility to construct scenes using Python or XML, or you can take it a step further by developing new C++ components. We also welcome contributions from the community to enhance and expand the capabilities of this plugin. @@ -15,26 +14,25 @@ We also welcome contributions from the community to enhance and expand the capab The Cosserat model has found applications in the realm of continuum robotics, particularly for simulating the deformation of robot bodies with geometries and mechanical properties akin to rods. This model aligns closely with the dynamic deformation patterns exhibited by soft manipulators, as it can effectively replicate nonlinear deformations encompassing bending, torsion, extension, and shearing. -One distinctive feature of Cosserat's theory, within the domain of continuous media mechanics, lies in its conceptualization: -it views each material point of an object as a rigid body with six degrees of freedom (three translations and three rotations). +One distinctive feature of Cosserat's theory, within the domain of continuous media mechanics, lies in its conceptualization: +it views each material point of an object as a rigid body with six degrees of freedom (three translations and three rotations). In contrast, many other models in continuum media mechanics tend to treat material points as particles with only three translation degrees of freedom. When modeling linear structures, this framework enables the creation of a structure closely resembling articulated solids, consisting of a series of rigid bodies whose relative positions are defined by their strain states. Consequently, this model serves as a versatile tool for modeling and controlling a variety of systems, including concentric tube robots, continuum robots driven by cables, or pneumatic soft robots with constant cross-sections. -## Theory -Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et. - -## Numerics -Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +Go into theorotical part of the plugin [Theory](docs/text/Theory.md) +Follow the tutorial : [cosserat_tutorial](docs/text/cosserat_tutorial.md) ## Some use cases -Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + ### Modeling and control + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. #### Direct control + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. #### Modeling cochlear implant using Discret Cosserat Model (DCM) diff --git a/docs/images/CosseratMapping.png b/docs/images/CosseratMapping.png new file mode 100644 index 00000000..547cd242 Binary files /dev/null and b/docs/images/CosseratMapping.png differ diff --git a/docs/images/PCS.png b/docs/images/PCS.png new file mode 100644 index 00000000..cbca6ea9 Binary files /dev/null and b/docs/images/PCS.png differ diff --git a/docs/images/Untitled.png b/docs/images/Untitled.png new file mode 100644 index 00000000..4ac5a8f4 Binary files /dev/null and b/docs/images/Untitled.png differ diff --git a/docs/images/exemple_curv_abs_input.png b/docs/images/exemple_curv_abs_input.png new file mode 100644 index 00000000..56c854c9 Binary files /dev/null and b/docs/images/exemple_curv_abs_input.png differ diff --git a/docs/images/exemple_rigid_translation.png b/docs/images/exemple_rigid_translation.png new file mode 100644 index 00000000..09dee2f2 Binary files /dev/null and b/docs/images/exemple_rigid_translation.png differ diff --git a/docs/images/frame1.png b/docs/images/frame1.png new file mode 100644 index 00000000..0cc020c9 Binary files /dev/null and b/docs/images/frame1.png differ diff --git a/docs/images/noeud_curv.png b/docs/images/noeud_curv.png new file mode 100644 index 00000000..1ab57cb9 Binary files /dev/null and b/docs/images/noeud_curv.png differ diff --git a/docs/images/position_90degres.png b/docs/images/position_90degres.png new file mode 100644 index 00000000..3c10d7dc Binary files /dev/null and b/docs/images/position_90degres.png differ diff --git a/docs/images/rigidbase.png b/docs/images/rigidbase.png new file mode 100644 index 00000000..f680fe4c Binary files /dev/null and b/docs/images/rigidbase.png differ diff --git a/docs/testScene/step1.py b/docs/testScene/step1.py new file mode 100644 index 00000000..1f09985b --- /dev/null +++ b/docs/testScene/step1.py @@ -0,0 +1,152 @@ +# -*- coding: utf-8 -*- + +import Sofa +from useful.params import Parameters + +from math import sin, cos, sqrt, pi + +# import os +# path = os.path.dirname(os.path.abspath(__file__))+'/mesh/' +# +# +# _tension = 0.0 +# class TensionComputing(Sofa.PythonScriptController): +# def initGraph(self, node): +# self.tension = 500 +# self.node = node; +# self.BeamHookeLawForce = self.node.getObject('BeamHookeLawForce') +# +# def onBeginAnimationStep(self, dt): +# self.tension = self.tension + 8000 * dt; +# self.BeamHookeLawForce.findData('tension').value = self.tension + +stiffness_param = 1.e10 +beam_radius = 1. +# params = Parameters(beamGeoParams=BeamGeometryParameters(init_pos=[0, 0, 0])) + + +def _add_rigid_base(p_node): + rigid_base_node = p_node.addChild('rigid_base') + rigid_base_node.addObject('MechanicalObject', template='Rigid3d', name="cosserat_base_mo", + position="0 0 0 0 0 0. 1", + showObject=1, showObjectScale='0.1') + rigid_base_node.addObject('RestShapeSpringsForceField', name='spring', stiffness=stiffness_param, + angularStiffness=stiffness_param, external_points="0", mstate="@cosserat_base_mo", + points="0", template="Rigid3d") + return rigid_base_node + + +def _add_cosserat_state(p_node, bending_states, list_sections_length, _radius=2.): + cosserat_coordinate_node = p_node.addChild('cosseratCoordinate') + cosserat_coordinate_node.addObject('MechanicalObject', template='Vec3d', name='cosserat_state', + position=bending_states) + cosserat_coordinate_node.addObject('BeamHookeLawForceField', crossSectionShape='circular', + length=list_sections_length, radius=2., youngModulus=1.e4, + poissonRatio=0.4) + return cosserat_coordinate_node + + +def _add_cosserat_frame(p_node, _bending_node, framesF, _section_curv_abs, _frame_curv_abs, _radius, _beam_mass=0.0): + cosserat_in_Sofa_frame_node = p_node.addChild('cosserat_in_Sofa_frame_node') + + _bending_node.addChild(cosserat_in_Sofa_frame_node) + frames_mo = cosserat_in_Sofa_frame_node.addObject('MechanicalObject', template='Rigid3d', + name="FramesMO", position=framesF, showIndices=1, showObject=1, + showObjectScale=0.8) + + cosserat_in_Sofa_frame_node.addObject('UniformMass', totalMass=_beam_mass) + + cosserat_in_Sofa_frame_node.addObject('DiscreteCosseratMapping', curv_abs_input=_section_curv_abs, + curv_abs_output=_frame_curv_abs, name='cosseratMapping', + input1=_bending_node.cosserat_state.getLinkPath(), + input2=p_node.cosserat_base_mo.getLinkPath(), + output=frames_mo.getLinkPath(), debug=0, radius=_radius) + return cosserat_in_Sofa_frame_node + + + +def createScene(root_node): + # + base_node = _add_rigid_base(root_node) + + # + cos_nul_state = [0.0, 0.0, 0.0] # torsion, y_bending, z_bending + bending_states = [cos_nul_state, cos_nul_state, cos_nul_state] + list_sections_length = [10, 10, 10] + bending_node = _add_cosserat_state(root_node, cos_nul_state, list_sections_length) + + section_curv_abs = [0, 10, 20, 30] + frames_curv_abs = [0., 5, 10, 15, 20, 25, 30] + cosserat_G_frames = [[0., 0, 0, 0, 0, 0, 1], [5., 0, 0, 0, 0, 0, 1], [10., 0, 0, 0, 0, 0, 1], + [15, 0, 0, 0, 0, 0, 1], [20., 0, 0, 0, 0, 0, 1], [25., 0, 0, 0, 0, 0, 1], + [30., 0, 0, 0, 0, 0, 1]] + + _add_cosserat_frame(base_node, bending_node, cosserat_G_frames, section_curv_abs, frames_curv_abs, + beam_radius) + + return root_node + + ############### + ## Rate of angular Deformation (2 sections) + ############### + + distance1 = [0.0, 0.2, 0.0] + distance2 = [0.0, 0.2, 0.0] + distance3 = [0.0, 0.2, 0.0] + _distance = [distance1, distance2, distance3] + + ddistance1 = [0.0, 0.0, 0.0] + ddistance2 = [0.0, 0.0, 0.0] + ddistance3 = [0.0, 0.0, 0.0] + _ddistance = [ddistance1, ddistance2, ddistance3] + + rateAngularDeformNode = rootNode.createChild('rateAngularDeform') + rateAngularDeformMO = rateAngularDeformNode.createObject('MechanicalObject', template='Vec3d', + name='rateAngularDeformMO', position=pos, + velocity='0 0 0 0 0 0 0 0 0', length='10 10 10', ) + # (2 series of 3 angles for 2 sections. we suppose that the lenght is 10 for each) + # BeamHookeLawForce = rateAngularDeformNode.createObject('CosseratInternalActuation', + # crossSectionShape='circular', length='10 10 10', radius='0.5', youngModulus='5e6') + BeamHookeLawForce = rateAngularDeformNode.createObject('CosseratInternalActuation', name="BeamHookeLawForce", + crossSectionShape='circular', length='10 10 10', + radius='0.5', + youngModulus='1e6', distance=_distance, ddistance=_ddistance, + tension=_tension) + rateAngularDeformNode.createObject('PythonScriptController', classname="TensionComputing") + + ############## + ## Frames + ############## + # the node of the frame needs to inherit from rigidBaseMO and rateAngularDeform + mappedFrameNode = rigidBaseNode.createChild('MappedFrames') + rateAngularDeformNode.addChild(mappedFrameNode) + framesMO = mappedFrameNode.createObject('MechanicalObject', template='Rigid3d', name="FramesMO", + position="0.5 0 0 0 0 0 1 5 0 0 0 0 0 1 10 0 0 0 0 0 1 15 0 0 0 0 0 1 20 0 0 0 0 0 1 25 0 0 0 0 0 1 30 0 0 0 0 0 1", + showObject='1', showObjectScale='1') + + # The mapping has two inputs: RigidBaseMO and rateAngularDeformMO + # one output: FramesMO + + inputMO = rateAngularDeformMO.getLinkPath() # + " " + RigidBaseMO.getLinkPath() + # inputMO = rateAngularDeformMO.getLinkPath() + inputMO_rigid = RigidBaseMO.getLinkPath() + outputMO = framesMO.getLinkPath() + # TODO: + mappedFrameNode.createObject('DiscretCosseratMapping', curv_abs_input='0 10 20 30', + curv_abs_output='0.5 5 10 15 20 25 30', input1=inputMO, input2=inputMO_rigid, + output=outputMO, debug='0') + + #### CylinderGridTop + CylinderCollision = mappedFrameNode.createChild('CylinderCollision') + + # CylinderCollision.createObject('MeshSTLLoader', filename=path+'trunk.stl', name='loader', rotation='0 90 0', scale='0.155') + CylinderCollision.createObject('CylinderGridTopology', name="loader", nx="8", ny="8", nz="20", length="30", + radius="0.5", axis="1 0 0") + CylinderCollision.createObject('Mesh', src='@loader') + CylinderCollision.createObject('MechanicalObject', template='Vec3d') + CylinderCollision.createObject('Triangle') + CylinderCollision.createObject('SkinningMapping', nbRef='2') + + # rootNode.createObject('BilateralInteractionConstraint', template='Rigid3d', object2='@rigidBase/MappedFrames/FramesMO', object1='@targetPos/target', first_point='0', second_point='6') + + return rootNode diff --git a/docs/testScene/tuto_1.py b/docs/testScene/tuto_1.py new file mode 100644 index 00000000..c0990b52 --- /dev/null +++ b/docs/testScene/tuto_1.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- + +import Sofa + +stiffness_param = 1.e10 +beam_radius = 1. + + +def _add_rigid_base(p_node): + rigid_base_node = p_node.addChild('rigid_base') + rigid_base_node.addObject('MechanicalObject', template='Rigid3d', name="cosserat_base_mo", + position="0 0 0 0 0 0. 1", + showObject=1, showObjectScale='0.1') + rigid_base_node.addObject('RestShapeSpringsForceField', name='spring', stiffness=stiffness_param, + angularStiffness=stiffness_param, external_points="0", mstate="@cosserat_base_mo", + points="0", template="Rigid3d") + return rigid_base_node + + +def _add_cosserat_state(p_node, bending_states, list_sections_length, _radius=2.): + cosserat_coordinate_node = p_node.addChild('cosseratCoordinate') + cosserat_coordinate_node.addObject('MechanicalObject', template='Vec3d', name='cosserat_state', + position=bending_states) + cosserat_coordinate_node.addObject('BeamHookeLawForceField', crossSectionShape='circular', + length=list_sections_length, radius=2., youngModulus=1.e4, + poissonRatio=0.4) + return cosserat_coordinate_node + + +def _add_cosserat_frame(p_node, _bending_node, framesF, _section_curv_abs, _frame_curv_abs, _radius, _beam_mass=0.0): + cosserat_in_Sofa_frame_node = p_node.addChild('cosserat_in_Sofa_frame_node') + + _bending_node.addChild(cosserat_in_Sofa_frame_node) + frames_mo = cosserat_in_Sofa_frame_node.addObject('MechanicalObject', template='Rigid3d', + name="FramesMO", position=framesF, showIndices=1, showObject=1, + showObjectScale=0.8) + + cosserat_in_Sofa_frame_node.addObject('UniformMass', totalMass=_beam_mass) + + cosserat_in_Sofa_frame_node.addObject('DiscreteCosseratMapping', curv_abs_input=_section_curv_abs, + curv_abs_output=_frame_curv_abs, name='cosseratMapping', + input1=_bending_node.cosserat_state.getLinkPath(), + input2=p_node.cosserat_base_mo.getLinkPath(), + output=frames_mo.getLinkPath(), debug=0, radius=_radius) + return cosserat_in_Sofa_frame_node + + +def createScene(root_node): + root_node.addObject('VisualStyle', displayFlags='showBehaviorModels showCollisionModels showMechanicalMappings') + root_node.gravity = [0, 0., 0] + # + base_node = _add_rigid_base(root_node) + + # + cos_nul_state = [0.0, 0.0, 0.0] # torsion, y_bending, z_bending + bending_states = [cos_nul_state, cos_nul_state, cos_nul_state] + list_sections_length = [10, 10, 10] + bending_node = _add_cosserat_state(root_node, bending_states, list_sections_length) + + section_curv_abs = [0, 10, 20, 30] + frames_curv_abs = [0., 5, 10, 15, 20, 25, 30] + cosserat_G_frames = [[0., 0, 0, 0, 0, 0, 1], [5., 0, 0, 0, 0, 0, 1], [10., 0, 0, 0, 0, 0, 1], + [15, 0, 0, 0, 0, 0, 1], [20., 0, 0, 0, 0, 0, 1], [25., 0, 0, 0, 0, 0, 1], + [30., 0, 0, 0, 0, 0, 1]] + + _add_cosserat_frame(base_node, bending_node, cosserat_G_frames, section_curv_abs, frames_curv_abs, + beam_radius) + + return root_node diff --git a/docs/testScene/tuto_2.py b/docs/testScene/tuto_2.py new file mode 100644 index 00000000..18ffcb64 --- /dev/null +++ b/docs/testScene/tuto_2.py @@ -0,0 +1,100 @@ +# -*- coding: utf-8 -*- + +import Sofa +from useful.params import Parameters + +stiffness_param = 1.e10 +beam_radius = 1. + + +def _add_rigid_base(p_node): + rigid_base_node = p_node.addChild('rigid_base') + rigid_base_node.addObject('MechanicalObject', template='Rigid3d', name="cosserat_base_mo", + position="0 0 0 0 0 0. 1", + showObject=1, showObjectScale='0.1') + rigid_base_node.addObject('RestShapeSpringsForceField', name='spring', stiffness=stiffness_param, + angularStiffness=stiffness_param, external_points="0", mstate="@cosserat_base_mo", + points="0", template="Rigid3d") + return rigid_base_node + + +def _add_cosserat_state(p_node, bending_states, list_sections_length, _radius=2.): + cosserat_coordinate_node = p_node.addChild('cosseratCoordinate') + print(f' ===> bendind state : {bending_states}') + cosserat_coordinate_node.addObject('MechanicalObject', template='Vec3d', name='cosserat_state', + position=bending_states) + cosserat_coordinate_node.addObject('BeamHookeLawForceField', crossSectionShape='circular', + length=list_sections_length, radius=2., youngModulus=1.e4, + poissonRatio=0.4) + return cosserat_coordinate_node + + +def _add_cosserat_frame(p_node, _bending_node, framesF, _section_curv_abs, _frame_curv_abs, _radius, _beam_mass=0.0): + cosserat_in_Sofa_frame_node = p_node.addChild('cosserat_in_Sofa_frame_node') + + _bending_node.addChild(cosserat_in_Sofa_frame_node) + frames_mo = cosserat_in_Sofa_frame_node.addObject('MechanicalObject', template='Rigid3d', + name="FramesMO", position=framesF, showIndices=0., showObject=0, + showObjectScale=0.8) + + cosserat_in_Sofa_frame_node.addObject('UniformMass', totalMass=_beam_mass) + + cosserat_in_Sofa_frame_node.addObject('DiscreteCosseratMapping', curv_abs_input=_section_curv_abs, + curv_abs_output=_frame_curv_abs, name='cosseratMapping', + input1=_bending_node.cosserat_state.getLinkPath(), + input2=p_node.cosserat_base_mo.getLinkPath(), + output=frames_mo.getLinkPath(), debug=0, radius=_radius) + return cosserat_in_Sofa_frame_node + + +def createScene(root_node): + root_node.addObject('VisualStyle', displayFlags='showBehaviorModels showCollisionModels showMechanicalMappings') + root_node.gravity = [0, 0., 0] + root_node.addObject('EulerImplicitSolver', firstOrder="0", rayleighStiffness="0.0", rayleighMass='0.0') + root_node.addObject('SparseLDLSolver', name='solver') + + # Add rigid base + base_node = _add_rigid_base(root_node) + + # build beam geometry + nb_sections = 6 + beam_length = 30. + length_s = beam_length/float(nb_sections) + bending_states = [] + list_sections_length = [] + temp = 0. # where to start the base position + section_curv_abs = [0.] # section/segment curve abscissa + + for i in range(nb_sections): + bending_states.append([0, 0.2, 0.]) # torsion, y_bending, z_bending + list_sections_length.append((((i + 1) * length_s) - i * length_s)) + temp += list_sections_length[i] + section_curv_abs.append(temp) + bending_states[nb_sections-1] = [0, 0.2, 0] + section_curv_abs[nb_sections] = beam_length + + # call add cosserat state and force field + bending_node = _add_cosserat_state(root_node, bending_states, list_sections_length) + + # comment : ??? + nb_frames = 6 + length_f = beam_length/float(nb_frames) + cosserat_G_frames = [] + frames_curv_abs = [] + cable_position_f = [] # need sometimes for drawing segment + x, y, z = 0, 0, 0 + + for i in range(nb_frames): + sol = i * length_f + cosserat_G_frames.append([sol + x, y, z, 0, 0, 0, 1]) + cable_position_f.append([sol + x, y, z]) + frames_curv_abs.append(sol + x) + + cosserat_G_frames.append([beam_length + x, y, z, 0, 0, 0, 1]) + cable_position_f.append([beam_length + x, y, z]) + frames_curv_abs.append(beam_length + x) + + _add_cosserat_frame(base_node, bending_node, cosserat_G_frames, section_curv_abs, frames_curv_abs, + beam_radius) + + return root_node diff --git a/docs/testScene/tuto_3.py b/docs/testScene/tuto_3.py new file mode 100644 index 00000000..dac6ad97 --- /dev/null +++ b/docs/testScene/tuto_3.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +""" + Cosserat class in SofaPython3. +""" + +__authors__ = "adagolodjo" +__contact__ = "adagolodjo@protonmail.com" +__version__ = "1.0.0" +__copyright__ = "(c) 2021,Inria" +__date__ = "October, 26 2021" + +from useful.header import addHeader, addSolverNode, addVisual +from useful.params import BeamPhysicsParameters, BeamGeometryParameters, SimulationParameters +from useful.params import Parameters +from cosserat.CosseratBase import CosseratBase + +geoParams = BeamGeometryParameters(init_pos=[0., 0., 0.], beamLength=30., showFramesObject=1, + nbSection=6, nbFrames=12, buildCollisionModel=0) +physicsParams = BeamPhysicsParameters(beamMass=1., youngModulus=1.0e4, poissonRatio=0.38, beamRadius=1., + beamLength=30) +simuParams = SimulationParameters() +Params = Parameters(beamGeoParams=geoParams, beamPhysicsParams=physicsParams, simuParams=simuParams) + + +def createScene(root_node): + addHeader(root_node) + root_node.gravity = [0, -9.81, 0.] + + solver_node = addSolverNode(root_node, name="solver_node") + + # create cosserat Beam + solver_node.addChild(CosseratBase(parent=solver_node, params=Params)) + + return root_node \ No newline at end of file diff --git a/docs/testScene/tuto_4.py b/docs/testScene/tuto_4.py new file mode 100644 index 00000000..41f31107 --- /dev/null +++ b/docs/testScene/tuto_4.py @@ -0,0 +1,125 @@ +# -*- coding: utf-8 -*- +""" + Cosserat class in SofaPython3. +""" + +__authors__ = "adagolodjo" +__contact__ = "adagolodjo@protonmail.com" +__version__ = "1.0.0" +__copyright__ = "(c) 2021,Inria" +__date__ = "October, 26 2021" + +from useful.header import addHeader, addSolverNode, addVisual +from useful.params import BeamPhysicsParameters, BeamGeometryParameters, SimulationParameters +from useful.params import Parameters +from cosserat.CosseratBase import CosseratBase +from math import sqrt +from splib3.numerics import Quat +import Sofa +from math import pi + +geoParams = BeamGeometryParameters(init_pos=[0., 0., 0.], beamLength=30., showFramesObject=1, + nbSection=6, nbFrames=12, buildCollisionModel=0) +physicsParams = BeamPhysicsParameters(beamMass=1., youngModulus=1.0e4, poissonRatio=0.38, beamRadius=0.5, + beamLength=30) +simuParams = SimulationParameters() +Params = Parameters(beamGeoParams=geoParams, beamPhysicsParams=physicsParams, simuParams=simuParams) + +force_null = [0., 0., 0., 0., 0., 0.] # N + + +class ForceController(Sofa.Core.Controller): + def __init__(self, *args, **kwargs): + Sofa.Core.Controller.__init__(self, *args, **kwargs) + self.forceNode = kwargs['forceNode'] + self.frames = kwargs['frame_node'].FramesMO + self.force_type = kwargs['force_type'] + self.tip_controller = kwargs['tip_controller'] + + self.size = geoParams.nbFrames + self.applyForce = True + self.forceCoeff = 0. + self.theta = 0.1 + + def onAnimateEndEvent(self, event): + if self.applyForce: + self.forceCoeff += 0.01 + else: + self.forceCoeff -= 0.01 + + # choose the type of force + if self.force_type == 1 : + self.compute_force() + elif self.force_type == 2: + self.compute_orthogonal_force() + elif self.force_type == 3: + self.rotate_force() + + def compute_force(self): + with self.forceNode.forces.writeable() as force: + vec = [0., 0., 0., 0., self.forceCoeff/sqrt(2), self.forceCoeff/sqrt(2)] + for i, v in enumerate(vec): + force[0][i] = v + + + def compute_orthogonal_force(self): + position = self.frames.position[self.size] # get the last rigid of the cosserat frame + orientation = Quat(position[3], position[4], position[5], position[6]) # get the orientation + # Calculate the direction of the force in order to remain orthogonal to the x axis of the last frame of the beam. + with self.forceNode.forces.writeable() as force: + vec = orientation.rotate([0., self.forceCoeff*5.e-2, 0.]) + vec.normalize() + # print(f' The new vec is : {vec}') + for count in range(3): + force[0][count] = vec[count] + + def rotate_force(self): + if self.forceCoeff <= 100. * pi: + with self.tip_controller.position.writeable() as position: + last_frame = self.frames.position[self.size] + vec = Quat(last_frame[3], last_frame[4], last_frame[5], last_frame[6]) # get the orientation + + vec.rotateFromEuler([self.theta, 0., 0.]) # apply rotation arround x-axis + vec.normalize() + for i, v in enumerate(vec): + position[0][i+3] = v + + + def onKeypressedEvent(self, event): + key = event['key'] + if key == "+": + self.applyForce = True + elif key == "-": + self.applyForce = False + + +def createScene(root_node): + addHeader(root_node) + root_node.gravity = [0, 0., 0.] + + solver_node = addSolverNode(root_node, name="solver_node") + + # create cosserat Beam + cosserat_beam = solver_node.addChild(CosseratBase(parent=solver_node, params=Params)) + cosserat_frames = cosserat_beam.cosseratFrame + + # this constance force is used only in the case we are doing force_type 1 or 2 + const_force_node = cosserat_frames.addObject('ConstantForceField', name='constForce', showArrowSize=1.e-8, indices=geoParams.nbFrames, + forces=force_null) + + # The endffectors is used only when force_type is 3 + #create a rigid body to control the end effector of the beam + tip_controller= root_node.addChild('tip_controller') + controller_state = tip_controller.addObject('MechanicalObject', template='Rigid3d', name="controlEndEffector", + showObjectScale=0.3, position=[geoParams.beamLength, 0, 0, 0, 0, 0, 1], showObject=True) + + cosserat_frames.addObject('RestShapeSpringsForceField', name='spring', + stiffness=1e8, angularStiffness=1e8, external_points=0, + external_rest_shape=controller_state.getLinkPath(), points=geoParams.nbFrames, template="Rigid3d") + + + solver_node.addObject(ForceController(forceNode=const_force_node, frame_node=cosserat_frames, force_type=3, + tip_controller=controller_state)) + + + return root_node \ No newline at end of file diff --git a/docs/text/Advanced Topics and Future Work.md b/docs/text/Advanced Topics and Future Work.md new file mode 100644 index 00000000..f21fe29c --- /dev/null +++ b/docs/text/Advanced Topics and Future Work.md @@ -0,0 +1,48 @@ + +**Slide 1: Advanced Topics in Soft Robotics** + +- Title: Advanced Topics in Soft Robotics +- Content: + - Introduction to advanced topics and emerging areas in the field of soft robotics. + - Discussion of how soft robots are being used in various applications. + - Brief overview of the evolving challenges and opportunities in the domain. + +--- + +**Slide 2: Applications of Soft Robots** + +- Title: Applications of Soft Robots +- Content: + - Detailed exploration of practical applications where soft robots are making an impact. + - Examples of industries and domains benefiting from soft robotics (e.g., medical, automation, exploration). + - Emphasis on real-world scenarios where soft robots provide unique advantages. + +--- +**Slide 3: Future Work and Research Directions** + +- Title: Future Work and Research Directions +- Content: + - Presentation of potential research areas and directions for future work in soft robotics. + - Addressing unsolved challenges and open questions in the field. + - Discussion of how the combination of FEM and DCM can be extended and improved. +--- + +**Slide 4: Robotics in Education and Training** + +- Title: Robotics in Education and Training +- Content: + - Highlighting the role of educational and training programs in fostering expertise in soft robotics. + - Discussing how tutorials, like the one being prepared, can contribute to knowledge dissemination. + - Encouraging the audience to explore and contribute to the advancement of soft robotics. + +--- + +**Slide 5: Conclusion and Call to Action** + +- Title: Conclusion and Call to Action +- Content: + - Summarizing the key points discussed in the Advanced Topics and Future Work section. + - Inspiring the audience to take an active role in the field of soft robotics. + - Encouraging collaboration, innovation, and exploration of advanced topics. + - Thanking the audience for their attention and participation. +--- diff --git a/docs/text/Background Concepts.md b/docs/text/Background Concepts.md new file mode 100644 index 00000000..70c3b24b --- /dev/null +++ b/docs/text/Background Concepts.md @@ -0,0 +1,71 @@ + +**Slide 1: Background Concepts - Introduction** + +- **Slide Title:** Understanding the Fundamentals + +**Content:** +- Briefly introduce the "Background Concepts" section. +- Explain that to grasp the hybrid FEM and DCM approach, participants need to understand some fundamental concepts. +- Highlight the importance of a strong foundation in soft robotics and simulation techniques. + +--- +**Slide 2: Soft Robotics Principles** + +- **Slide Title:** Soft Robotics: Core Principles + +**Content:** +- Define the core principles of soft robotics, including compliance, flexibility, and adaptability. +- Use images and examples to illustrate these principles. +- Emphasize the fundamental differences between soft robots and traditional rigid robots. +--- +[[cosserat_python_scene]] + + +--- +||X|Y|Z| +|---|---|---|---| +|0|0|0|0| +|1|0|0|0| +|2|0|0|0| +|3|0|0|0| +|4|0|0|0| +|5|0|0|-2.35| + + +--- + +**Slide 3: Finite Element Methods (FEM)** + +- **Slide Title:** FEM: A Cornerstone of Soft Robot Simulation + +**Content:** +- Provide an overview of Finite Element Methods (FEM) and their role in simulating soft robots. +- Explain how FEM breaks down complex structures into smaller elements. +- Describe how FEM handles material properties, deformations, and forces. +- Showcase real-world applications of FEM in soft robotics. + +--- + +**Slide 4: Deformable Continuous Models (DCM)** + +- **Slide Title:** DCM: Modeling Cable-Driven Mechanisms + +**Content:** +- Define Deformable Continuous Models (DCM) and their significance in soft robotics. +- Explain how DCM focuses on modeling cables and deformations in soft robots. +- Discuss the advantages of DCM, such as the representation of cable-driven actuation. +- Share practical examples of DCM applications in soft robotics. + +--- + +**Slide 5: Bridging the Gap with Hybrid Modeling** + +- **Slide Title:** Hybrid Modeling: Combining FEM and DCM + +**Content:** +- Introduce the core concept of the tutorial: the integration of FEM and DCM for more accurate simulations. +- Explain the motivations behind this hybrid approach. +- Highlight the complementary nature of FEM and DCM in simulating different aspects of soft robots. +- Preview the real-world implications and benefits of this hybrid modeling strategy. + +--- diff --git a/docs/text/Brouillons.md b/docs/text/Brouillons.md new file mode 100644 index 00000000..7f988840 --- /dev/null +++ b/docs/text/Brouillons.md @@ -0,0 +1,40 @@ + +**Overview** +Remember to make the tutorial interactive, engage the participants, and provide opportunities for questions and discussions. You may also consider sharing the tutorial materials, code, and relevant resources with participants for further learning and experimentation. + +--- +**Partie 1:** +Each slide should be visually engaging with relevant images, diagrams, and minimal text. You can also use this opportunity to set the tone for the tutorial, making it clear that participants are embarking on an exciting journey into the world of soft robotics simulations. + +--- +**Partie 2:** +Each slide should be visually appealing, with clear and concise explanations. Make use of diagrams, images, and bullet points to enhance understanding. The aim is to provide participants with a solid foundation in the background concepts essential for grasping the hybrid FEM and DCM approach. + +--- + +Configuring the environment with SOFA and the Cosserat plugin is a critical step in your soft robotics simulation journey. This subsection serves as a foundation for the practical implementation of the hybrid FEM and DCM approach, allowing you to accurately model and simulate soft robots with complex deformations and interactions. + +--- +- Voir Deformable Continuous Models (DCM) + +--- + +These five slides will provide a detailed overview of the "Inverse Simulation" subsection, explaining the purpose, examples, computational aspects, and concluding remarks. This will help your audience understand the role of Inverse Simulation in soft robotics. + +--- +These five slides will provide a detailed overview of the "Model Convergence and Sensitivity Analysis" subsection, explaining the purpose, examples, implications, and concluding remarks. This will help your audience understand the significance of these analyses in soft robotics. + +--- + +These five slides will provide a detailed overview of advanced topics, potential applications, future research directions, and the role of education and training in soft robotics. It will also motivate the audience to engage in the field and contribute to its growth. + + +---- +These ten slides incorporate elements from the provided paper and database, delivering a detailed introduction to the hybrid framework, its motivations, objectives, and contributions. It also includes an overview of FEM, DCM, advanced topics, and future work in the realm of soft robotics. The presentation concludes by encouraging the audience to explore the full paper for further information. + +--- + + +These ten slides provide a detailed introduction to the hybrid framework, its motivation, objectives, and contributions, as well as an overview of FEM, DCM, and a glimpse of advanced topics and future work in the field of soft robotics. It concludes by motivating the audience to explore the paper's contents. + +--- diff --git a/docs/text/Complement.md b/docs/text/Complement.md new file mode 100644 index 00000000..faa8340b --- /dev/null +++ b/docs/text/Complement.md @@ -0,0 +1,82 @@ +Certainly, here is an updated version of the extended introduction section with ten detailed slides, incorporating elements from the provided paper and relevant content from my database: + +**Slide 1: Title and Introduction** + +- Title: Introduction to the Hybrid Framework for Soft Robotics +- Content: + - Introduce the audience to the paper, "Hybrid Framework for Real-Time Simulation of Soft Robots." + - Highlight the focus on combining Finite Element Method (FEM) and Discrete Cosserat Models (DCM) in soft robotics. + - Briefly mention the key points covered in the following slides. + +**Slide 2: Soft Robots in Modern Applications** + +- Title: Soft Robots in Modern Applications +- Content: + - Showcase real-world examples of soft robots' applications in various domains. + - Cite specific instances where soft robots have revolutionized medical, industrial, and exploration fields. + - Highlight the need for adaptable and safe robotic systems. + +**Slide 3: Challenges in Soft Robotics Modeling** + +- Title: Modeling Challenges in Soft Robotics +- Content: + - Explain the unique modeling challenges in soft robotics arising from deformable materials. + - Discuss the importance of real-time simulations for control and decision-making in such robots. + - Reference previous research in the field that addresses these challenges. + +**Slide 4: The Hybrid Approach's Promise** + +- Title: Promise of a Hybrid Framework +- Content: + - Detail the motivations behind developing a hybrid framework combining FEM and DCM. + - Present the advantages of using FEM for deformable materials and DCM for cable-driven robots. + - Provide examples of applications where the hybrid framework can excel. + +**Slide 5: Research Objectives and Contributions** + +- Title: Research Objectives and Contributions +- Content: + - Define the primary objectives of the research presented in the paper. + - Highlight the key contributions this paper offers to the field of soft robotics. + - Give the audience a glimpse of what to expect in the upcoming sections. + +**Slide 6: Paper Structure and Roadmap** + +- Title: Paper Structure and Roadmap +- Content: + - Offer an overview of the paper's structure, detailing each section's focus. + - Provide a roadmap to guide the audience through different aspects of the hybrid framework. + - Help the audience navigate and follow the presentation. + +**Slide 7: The Role of FEM in Soft Robotics** + +- Title: Finite Element Method in Soft Robotics +- Content: + - Explain the role of FEM in modeling deformable materials for soft robots. + - Cite examples of soft robot components where FEM has been effectively applied. + - Emphasize FEM's capacity to handle geometric non-linearity. + +**Slide 8: Introduction to DCM for Cable-Driven Robots** + +- Title: Discrete Cosserat Models for Cable-Driven Robots +- Content: + - Delve into the details of DCM and its suitability for modeling cable-driven robots in soft robotics. + - Showcase real-world applications of cable-driven soft robots. + - Explain how DCM handles reduced coordinates for modeling efficiency. + +**Slide 9: Advanced Topics and Future Directions** + +- Title: Advanced Topics and Future Directions +- Content: + - Provide a preview of advanced topics that will be discussed later in the paper. + - Offer insights into potential future research directions in the field of soft robotics. + - Encourage the audience to explore these exciting areas for further study. + +**Slide 10: Conclusion and Call to Action** + +- Title: Conclusion and Call to Action +- Content: + - Summarize the importance of the hybrid framework for soft robotics. + - Invite the audience to read the full paper for comprehensive insights into the topic. + - Express gratitude for the audience's attention and participation. + diff --git a/docs/text/Direct Simulation.md b/docs/text/Direct Simulation.md new file mode 100644 index 00000000..82af0d81 --- /dev/null +++ b/docs/text/Direct Simulation.md @@ -0,0 +1,51 @@ +--- +title: Introduction to Direct Simulation +--- + +--- +**Slide 1: Introduction to Direct Simulation** + +- Title: Introduction to Direct Simulation +- Content: + - Definition of Direct Simulation. + - Purpose of Direct Simulation in soft robotics. + - Importance of accurately modeling deformable robots in real-time. + - Overview of the content covered in this subsection. +--- +**Slide 2: Simulation Setup** + +- Title: Simulation Setup +- Content: + - Detailed explanation of the simulation environment setup. + - Mention of the software used (SOFA) and the Cosserat plugin. + - Steps for setting up SOFA and enabling the Cosserat plugin. + - Loading example scenes for practical experimentation. + +--- +**Slide 3: Soft Gripper Example** + +- Title: Soft Gripper Example +- Content: + - Introduction to the soft gripper used in the simulation. + - Discussion on its mechanical properties and complexity. + - Highlighting the integration of DCM to simulate the cables. + - Mention of friction and contact constraints for realistic interaction with a rigid object. +--- +**Slide 4: Observations and Analysis** + +- Title: Observations and Analysis +- Content: + - Presentation of the results from the direct simulation of the soft gripper. + - Discussion on the influence of cable properties (e.g., radius) on the gripper's deformation. + - Emphasis on the effect of using pre-bent rods for manipulation. + - Visualization of stress levels in cables and materials. +--- +**Slide 5: Conclusions from Direct Simulation** + +- Title: Conclusions from Direct Simulation +- Content: + - Summarizing the key findings from the direct simulation experiments. + - Emphasis on the importance of accurately modeling cables and their interaction with deformable structures. + - Relating the results to the overall objective of combining FEM and DCM for soft robotics. + - Transition to the next subsection on "Inverse Simulation" and the broader tutorial structure. +--- diff --git a/docs/text/Introduction.md b/docs/text/Introduction.md new file mode 100644 index 00000000..6dd03e7c --- /dev/null +++ b/docs/text/Introduction.md @@ -0,0 +1,62 @@ +--- +tutorial: Introduction +tags: + - tuto/cosserat +cssclass: + - dashboard +--- +## Introduction to Soft Robotics (SR) + +- Soft robotics is an emerging and innovative field of robotics +- Focuses on the design and development of robots made from : + - *Flexible*, + - *Deformable*, + - *Compliant materials*. +--- +## Introduction to Soft Robotics (SR) +- Numerous advantages + - *Adaptability* : Their ability to deform and adapt to their environment + - *Safety* : Ideal for interactions with humans, delicate objects, or unstructured surroundings + - *Versatility* : Various applications + +--- +## **Key Applications** + +- *Healthcare* : The gentle and non-invasive nature of SR is necessary +- *Industrial automation* : The high [Compliance](../../../Soft_Robot/Compliance.md), reduces the risk of damage during interactions with products +- *Search and rescue* : they can navigate through tight spaces and uneven terrains +- *Space exploration*, and *extreme environments* + +--- +## **Challenges in Soft Robotics** + +- *Modeling* : due to deformable materials +- [*Control*](../../../Soft_Robot/kinematics_dynamics_control.md) : due to the non-linear, multi-body dynamics of deformable materials +- [*Multi-dimension*](../../../../../../Projects/ANR/brainStormingANR2023.md) : due to a wide range of shape, volume (3D), surface (2D) and cable (1D) +- [*Multi-physics*](../../../../../../Projects/ANR/RobotMulti-physics.md) : due a wide range of physical behaviors, including mechanical deformation, thermal effects, electrical responses, + +--- +## **Challenges in Soft Robotics** + +- Addressing these challenges is crucial for the widespread adoption of soft robots in various fields. +(To go further on the introduction of deformable robotics ⇾ [Introduction_General](../../../Soft_Robot/Introduction_General.md) ) + +--- +## [FEM and DCM](../../_docs/DCM_FEM.md) + +- *FEM's Material Modeling*: FEM excels at modeling the deformations and stress distributions in complex materials, including soft and deformable ones. It considers the local behavior of materials, making it more accurate for understanding the mechanical properties of soft robots. +- *Cosserat theory's Beam-Like Modeling*: DCM, on the other hand, is suitable for modeling the overall shape and bending of structures, making it a natural choice for cables, rods, and flexible elements in soft robots. + + +--- +## Motivation for the combination of the two models + +- *Combined Accuracy*: By combining FEM and DCM, you can leverage the strengths of both methods. FEM provides fine-grained material modeling, while DCM captures the shape and motion of deformable elements accurately. This leads to a more realistic representation of the entire robot's behavior. + +- *Unified Simulation Framework*:A combined FEM-DCM framework creates a unified simulation environment that can model both the deformable body of the robot (using FEM) and the actuation components (using DCM). This simplifies simulation setup and control algorithms. + +--- + +--- + +[[Complement]] \ No newline at end of file diff --git a/docs/text/Inverse Simulation.md b/docs/text/Inverse Simulation.md new file mode 100644 index 00000000..3e8b6f27 --- /dev/null +++ b/docs/text/Inverse Simulation.md @@ -0,0 +1,46 @@ + +**Slide 1: Introduction to Inverse Simulation** + +- Title: Introduction to Inverse Simulation +- Content: + - Definition and purpose of Inverse Simulation in the context of soft robotics. + - Highlighting the role of Inverse Simulation in controlling deformable robots. + - Setting the stage for understanding how to determine cable actuation based on desired end-effector motion. +--- + +**Slide 2: Soft Finger Inverse Simulation** + +- Title: Soft Finger Inverse Simulation +- Content: + - Introduction to the soft finger model used for Inverse Simulation. + - Discussion on the complexity of the problem. + - Overview of the inputs and unknowns in the Inverse Simulation. + - Mention of constraints, including sliding constraints between DCM cable model and FEM silicone finger model. +--- +**Slide 3: Soft Tentacle Inverse Simulation** + +- Title: Soft Tentacle Inverse Simulation +- Content: + - Presentation of the soft tentacle robot used as an example for Inverse Simulation. + - Description of the scenario where the effector follows a predefined trajectory. + - Explanation of cable actuation to achieve desired end-effector motion. + - Highlighting the importance of controlling multiple cables in the inverse problem. +--- +**Slide 4: Timing and Computational Considerations** + +- Title: Timing and Computational Considerations +- Content: + - Discussing the computational resources required for Inverse Simulation. + - Mentioning the hardware used for the simulations. + - Providing a table with details on the number of elements, constraints, and computational time for each simulation scenario. + - Comparing the computational time between direct and inverse simulations. +--- +**Slide 5: Conclusions from Inverse Simulation** + +- Title: Conclusions from Inverse Simulation +- Content: + - Summarizing the key takeaways from the Inverse Simulation experiments. + - Emphasizing the challenges and complexities of solving inverse problems for deformable robots. + - Relating the results to the overall objective of combining FEM and DCM for soft robotics. + - Transition to the conclusion of the tutorial and future work. +--- diff --git a/docs/text/Model Convergence and Sensitivity Analysis.md b/docs/text/Model Convergence and Sensitivity Analysis.md new file mode 100644 index 00000000..61d482a7 --- /dev/null +++ b/docs/text/Model Convergence and Sensitivity Analysis.md @@ -0,0 +1,51 @@ + + +**Slide 1: Introduction to Model Convergence and Sensitivity Analysis** + +- Title: Introduction to Model Convergence and Sensitivity Analysis +- Content: + - Definition and purpose of Model Convergence and Sensitivity Analysis in the context of soft robotics. + - Explanation of why it's important to assess the convergence of the model and analyze its sensitivity. + - Setting the stage for understanding how variations in model parameters impact the behavior of deformable robots. + +--- + +**Slide 2: Assessing Model Convergence** + +- Title: Assessing Model Convergence +- Content: + - Discussing the concept of model convergence in the context of deformable robots. + - Explanation of how the model's behavior changes with varying numbers of sections. + - Presenting a specific example (soft finger) and its convergence with different numbers of cable sections. + - Highlighting the role of section numbers in ensuring a converged model. +--- +**Slide 3: Analyzing Model Sensitivity** + +- Title: Analyzing Model Sensitivity +- Content: + - Introduction to model sensitivity analysis for deformable robots. + - Explanation of how variations in parameters affect the model's response. + - Presenting results of sensitivity analysis in the context of cable radius. + - Discussing the observed impact on the deformation of the silicone finger with varying cable radii. + +--- + +**Slide 4: Implications for Design and Control** + +- Title: Implications for Design and Control +- Content: + - Discussing the practical implications of model convergence and sensitivity analysis. + - Explaining how these analyses can inform the design of soft robotic systems. + - Emphasizing the importance of parameter choices in controlling deformable robots. + - Providing insights into how these findings can be applied in real-world soft robotics applications. + +--- +**Slide 5: Conclusions from Model Convergence and Sensitivity Analysis** + +- Title: Conclusions from Model Convergence and Sensitivity Analysis +- Content: + - Summarizing the key takeaways from the Model Convergence and Sensitivity Analysis. + - Relating the results to the overall objective of combining FEM and DCM for soft robotics. + - Highlighting the significance of understanding convergence and sensitivity in modeling. + - Transitioning to the conclusion of the tutorial and future work. +--- diff --git a/docs/text/Numerics.md b/docs/text/Numerics.md new file mode 100644 index 00000000..ebef7763 --- /dev/null +++ b/docs/text/Numerics.md @@ -0,0 +1,10 @@ + +### Spatial Discretization + +### Time Discretization + +### Reduce to Global State + +### Global to Reduce State + +### Boundary conditions and interaction forces \ No newline at end of file diff --git a/docs/text/Setting up the Environment.md b/docs/text/Setting up the Environment.md new file mode 100644 index 00000000..75c845c4 --- /dev/null +++ b/docs/text/Setting up the Environment.md @@ -0,0 +1,232 @@ +--- +cssclasses: + - dashboard + - multi-column + - two-column-list +tags: + - tuto/cosserat +--- + + +**Introduction to SOFA** +- Have SOFA installed on your machine +- Install Cosserat plugin + - In Tree + - Out Tree + +--- + +**Step 1: Installing SOFA** + +Before you begin with the specific Cosserat plugin, you need to install SOFA. Follow these steps: + +1. Go to the official SOFA website (https://www.sofa-framework.org/) to download the latest version. +2. Choose the appropriate version for your operating system (Windows, Linux, or macOS). +3. Follow the installation instructions for your OS. Typically, this involves extracting the downloaded archive and setting environment variables. +--- + +**Step 2: Setting Up the Cosserat Plugin** + +Now, we'll dive into the essential part – configuring the Cosserat plugin within SOFA. +1. **Create plugins folder:** + - Create folder externalPlugins + - **sofa** + - ├── **src** + - ├── **build** + - ├── **externalPlugins** + +--- +2. **Obtaining the Plugin:** +- GitHub : https://github.com/SofaDefrost/Cosserat + - Download the plugin : + - git clone git@github.com:SofaDefrost/Cosserat.git (if you are using ssh-key) + - git clone https://github.com/SofaDefrost/Cosserat.git + - or Download the **Zip** +--- + +**3. Add *CMakeList.txt* file inside the *externalPlugin* folder** +```Cmake + cmake_minimum_required(VERSION 3.1) + sofa_find_package(SofaFramework) + + sofa_add_subdirectory(plugin SofaPython3 SofaPython3 ON) # If you want to use python + sofa_add_subdirectory(plugin STLIB STLIB ON) # If you want to use python & Cosserat prefabs + sofa_add_subdirectory(plugin Cosserat Cosserat ON) +``` + +--- + +**4. Activating the Plugin:** To activate the Cosserat plugin, follow these steps: + +- Open your terminal and go to SOFA's **build-directory** + - run + ```bash + cmake-gui . + ``` + - In the *Search* bar, type **external**, + - In $SOFA\_EXTERNAL\_DIRECTORIES$ + - Fill in the empty box with: + - **path-to-cosserat-directory** + - Find the Cosserat plugin and enable it +--- + +5. **First Cosserat Scene: *tuto_1.py*** + - As said previously, this component is based on the PCS (Piece-wise Constant Strain) formulation. + ![400](Pasted%20image%2020231102173536.png) +--- + +- [ ] 3 sections with 7 frames +- [ ] **Goals** : + - how to create a basic scene with the cosserat plugin + - It is important to note the difference between : + - **section** and **frames** + - **section** and **cross-section** + - The notion of force-field : here **BeamHookeLawForceField** + - The notion of mapping: here **DiscreteCosseratMapping** + - Functions: **apply, applyJ**, **applyJT** for forces and **ApplyJ^T** for constraints +--- +Start with the base +![500](images/exemple_rigid_translation.png) + +--- + +- The beam is always constructed along the x-axis +```python + def _add_rigid_base(p_node): + rigid_base_node = p_node.addChild('rigid_base') + rigid_base_node.addObject('MechanicalObject', template='Rigid3d', name="cosserat_base_mo", position="0 0 0 0 0 0. 1", showObject=1, showObjectScale='0.1') + rigid_base_node.addObject('RestShapeSpringsForceField', name='spring', stiffness=stiffness_param, angularStiffness=stiffness_param, external_points="0", mstate="@cosserat_base_mo", points="0", template="Rigid3d") + return rigid_base_node +``` + +--- +- Add Cosserat **Reduced coordinates** states (torsion and bending along y and z-axis) +- Add **BeamHookeLawForceField** based on the Hooke's Law +```python +def _add_cosserat_state(p_node, bending_states, list_sections_length, _radius=2.): + cosserat_coordinate_node = p_node.addChild('cosseratCoordinate') + cosserat_coordinate_node.addObject('MechanicalObject', template='Vec3d', name='cosserat_state', position=bending_states) + cosserat_coordinate_node.addObject('BeamHookeLawForceField', crossSectionShape='circular', length=list_sections_length, radius=2., youngModulus=1.e4, poissonRatio=0.4) + return cosserat_coordinate_node +``` + +--- +- Parameters : +```python +list_sections_length = [10, 10, 10] +cos_nul_state = [0.0, 0.0, 0.0] # torsion, y_bending, z_bending +bending_states = [cos_nul_state, cos_nul_state, cos_nul_state] +``` +--- +- **BeamHookeLawForceField** + - **Force Computation**: The `addForce` method calculates and adds the forces acting on the beams. It uses Hooke's law to compute the forces based on the deformation of the beams and their properties. The computed forces are then stored in the `f` variable. +--- +- **Derivative of Force Computation**: The `addDForce` method computes the derivative of the forces with respect to the deformation. This is used for stiffness matrix calculations in the context of finite element simulations. + +--- + +- **Stiffness Matrix Computation**: The `addKToMatrix` method is responsible for adding the stiffness matrix to the global matrix. This is used in FEM to represent the stiffness of the entire system. +--- +- Add Mapped coordinates (frames) to the scene + - **Mapping** between **Reduced coordinates** (Cosserat's state) and Global cordinates (Sofa state). + - Frames are multi-mapped (under Cosserat state and rigid base) +![400](../images/CosseratMapping.png) +--- + +```python +def _add_cosserat_frame(p_node, _bending_node, framesF, _section_curv_abs, _frame_curv_abs, _radius, _beam_mass=0.0): + cosserat_in_Sofa_frame_node = p_node.addChild('cosserat_in_Sofa_frame_node') + _bending_node.addChild(cosserat_in_Sofa_frame_node) + frames_mo = cosserat_in_Sofa_frame_node.addObject('MechanicalObject', template='Rigid3d', name="FramesMO", position=framesF, showIndices=0., showObject=0, showObjectScale=0.8) + + cosserat_in_Sofa_frame_node.addObject('UniformMass', totalMass=_beam_mass) + cosserat_in_Sofa_frame_node.addObject('DiscreteCosseratMapping', curv_abs_input=_section_curv_abs, curv_abs_output=_frame_curv_abs, name='cosseratMapping', input1=_bending_node.cosserat_state.getLinkPath(), input2=p_node.cosserat_base_mo.getLinkPath(), output=frames_mo.getLinkPath(), debug=0, radius=_radius) + return cosserat_in_Sofa_frame_node +``` +--- +- The notion of mapping: here **DiscreteCosseratMapping** + - **apply** : It calculates how the positions of elements in the input models (deformations and base) are transformed to the output model (rigid frames). The function applies the mapping to these input positions and updates the output frames accordingly. + - **applyJ** : compute the Jacobian matrix for the mapping operation. How small changes in input velocity (in this case, deformations) affect small changes in output velocity (in this case, the rigid frames). +--- + +- **applyJT force** : It updates forces in reduced coordinate based on forces in global coordinate. +- **applyJT Constraint** : It updates constraints in reduced coordinate based on constraints in global coordinate. + +---- +- [ ] Example 2: **tuto_2.py** + - [ ] script for automating sections and frames + - [ ] **Goal**: show the role of the number of sections on the overall deformation + - [ ] Example: + - [ ] 6 sections; 32 frames: $b_y=0.2$ on the last bending_state + - [ ] 12 sections 32 frames: $b_y=0.2$ on the last bending_state + - [ ] 6 sections 6 frames: all variables $b_y=0.2$ + - [ ] Change to frames = 12/24/32 + - [ ] Shows that we have a smoother curvature than previously while emphasizing the fact that there is rather a geometry impact, but not a physical one. +---- + +- [ ] Scene **![tuto_3](../testScene/tuto_3.py)** + - [ ] Use the $CosseratBase$ Python class and $prefabs$ +```python +def createScene(root_node): + addHeader(root_node) + root_node.gravity = [0, -9.81, 0.] + solver_node = addSolverNode(root_node, name="solver_node") + + # create cosserat Beam + solver_node.addChild(CosseratBase(parent=solver_node, params=Params)) + return root_node +``` +--- +- [ ] Uses also python $dataclass$ +```python +- geoParams = BeamGeometryParameters(init_pos=[0., 0., 0.], beamLength=30., showFramesObject=1,nbSection=6, nbFrames=12, buildCollisionModel=0) +- physicsParams = BeamPhysicsParameters(beamMass=1., youngModulus=1.0e4, poissonRatio=0.38, beamRadius=1., beamLength=30) +- simuParams = SimulationParameters() +- Params = Parameters(beamGeoParams=geoParams, beamPhysicsParams=physicsParams, simuParams=simuParams) + +``` +--- +- [ ] Scene ![tuto_4](../testScene/tuto_4.py) + - [ ] Force type 1 + - [ ] Force type 2 + - [ ] Force type 3 + +--- + +- [ ] Une scène avec contrainte +- [ ] Celle de l’actuation du doigt **[tuto7.py](http://tuto7.py)** +--- + +- [ ] Celles des trois doigts qui soulèvent le cube ****[tuto8.py](http://tuto8.py)*** + +---- + +- [ ] **Une scène pre-bent, s'inspire de la scène Flavie **[tuto9.py](http://tuto9.py)** + + +--- + +**Step 3: Configuring Scene Files** + +Now that you have SOFA and the Cosserat plugin ready, you need to configure your simulation scene files. These XML-based files define the simulation environment, including the soft robot model, forces, constraints, and interaction with the environment. + +--- + +1. **Creating a Scene File:** You can start by creating a new XML scene file. This file will serve as the blueprint for your simulation. You can use a text editor to create and modify it. +--- + +2. **Defining Soft Robot Models:** Within the scene file, you must define your soft robot model. You can specify its geometry, material properties, and the use of Cosserat models to represent deformable structures. +--- +3. **Integrating Cosserat Components:** To utilize Cosserat models in your simulation, you need to incorporate the appropriate components from the Cosserat plugin. These components include the Cosserat beam elements, which are crucial for modeling cables and rods. +--- +4. **Adding Constraints:** Depending on your simulation, you might need to introduce constraints that describe the interaction between the robot and its environment. This is also an essential part of configuring the scene. +--- +5. **Configuring Simulation Parameters:** The scene file allows you to set various simulation parameters, such as time steps, numerical solvers, and visualization options. + +--- + +**Step 4: Running Simulations** + +After configuring your scene file, you can run simulations to see how the soft robot behaves. SOFA provides real-time visualization, making it easier to analyze and refine your models. You can interact with the simulated robot and monitor its performance as the simulation progresses. + +--- diff --git a/docs/text/Soft_robot_intro.md b/docs/text/Soft_robot_intro.md new file mode 100644 index 00000000..c21abe9e --- /dev/null +++ b/docs/text/Soft_robot_intro.md @@ -0,0 +1,69 @@ +--- +title: Introduction to Soft Robotics +--- + + +**Slide 1: Soft Robotics - A New Frontier** + +- Content: + - Soft robotics is an emerging and innovative field of robotics that focuses on the design and development of robots made from flexible, deformable, and compliant materials. + - Soft robotics is a cutting-edge field that focuses on the design and development of robots using compliant and deformable materials. + - These robots are in stark contrast to traditional rigid robots and offer numerous advantages, including adaptability, safety, and versatility in various applications. + +--- +**Slide 2: Characteristics of Soft Robots** + +- Content: + - Soft robots are characterized by their ability to deform and adapt to their environment, making them ideal for interactions with humans, delicate objects, or unstructured surroundings. + - Their compliance and flexibility are key attributes that enable them to handle complex tasks. + +--- + +**Slide 3: Applications in Healthcare** + +- Content: + - Soft robotics has found significant applications in the healthcare industry, where the gentle and non-invasive nature of soft robots is leveraged for tasks such as minimally invasive surgery and rehabilitation. + - Examples include surgical robots that can navigate delicate tissues with precision. +--- + +**Slide 4: Industrial Automation** + +- Content: + - In industrial automation, soft robots are increasingly used for tasks such as pick-and-place operations, packaging, and assembly. + - The compliance of soft robots reduces the risk of damage during interactions with products. +--- +**Slide 5: Search and Rescue Operations** + +- Content: + - Soft robots are being explored for search and rescue operations, where they can navigate through tight spaces and uneven terrains. + - These robots can be vital in disaster-stricken areas to locate survivors. + +**Slide 6: Space Exploration and Extreme Environments** + +- Content: + - Soft robots have potential applications in space exploration due to their ability to adapt to different environments. + - They can also be used in extreme environments on Earth, such as deep-sea exploration or nuclear decommissioning. + +**Slide 7: Challenges in Soft Robotics** + +- Content: + - Despite their promise, soft robots present unique challenges in modeling, control, and actuation. + - Addressing these challenges is crucial for the widespread adoption of soft robots in various fields. + +**Slide 8: Interdisciplinary Nature** + +- Content: + - Soft robotics is inherently interdisciplinary, drawing from fields like materials science, biomechanics, and control theory. + - Collaboration between experts from different domains is essential to advance the field. + +**Slide 9: Future Directions** + +- Content: + - The field of soft robotics continues to evolve, with ongoing research to overcome challenges and expand applications. + - Future directions include advancements in materials, control strategies, and the integration of soft robots into everyday life. + +**Slide 10: Conclusion** + +- Content: + - In conclusion, soft robotics represents a paradigm shift in the field of robotics, offering exciting possibilities for various industries. + - As technology advances and interdisciplinary collaboration thrives, soft robots are poised to transform the way we interact with machines and the world around us. \ No newline at end of file diff --git a/docs/text/Theory.md b/docs/text/Theory.md new file mode 100644 index 00000000..d40f71dd --- /dev/null +++ b/docs/text/Theory.md @@ -0,0 +1,40 @@ +--- +marp: +tags: + - tuto/cosserat +cssclasses: + - multi-column + - two-column-list + - two-columns +--- + +Solide Works +![](Pasted%20image%2020231025171449.png) + +--- + +![[Learning/Learning&Development/Formation/cosserat/docs/text/Untitled Diagram.svg]] + +--- + +#### Mathematical Description of Cosserat Rods + +##### Cosserat differential Kinematics + +>[!blank-container] +>- Configuration $g= \begin{pmatrix} \mathcal{R} & u \\ 0 & 1 \end{pmatrix} ∈SE(3)$ +>- Velocity $\eta(s,t) =\begin{align}y &= \begin{bmatrix}\mathcal{w} \\ \mathcal{v} \end{bmatrix}\end{align} \in R^6$ +>- Strain $\xi(s,t) =\begin{align}y &= \begin{bmatrix}\mathcal{k} \\ \mathcal{p} \end{bmatrix}\end{align} \in R^6$ + +--- +#### Reference Frames + +--- + +### Conservation of Momentum + +--- +### Linear Elasticity + + +--- \ No newline at end of file diff --git a/docs/text/cosserat_python_scene.md b/docs/text/cosserat_python_scene.md new file mode 100644 index 00000000..c27d84ae --- /dev/null +++ b/docs/text/cosserat_python_scene.md @@ -0,0 +1,137 @@ +# Principes de base + + + +## Théorie de Cosserat + +Cosserat sur base sur la notion de _Piecewise Constant Strain_. Elle repose sur le fait d’estimer la **deformation** de manière très grossière, comme ci-dessous. + +![PCS.png](images/PCS.png) + +### Base rigide + +![rigidbase.png](images/rigidbase.png) + +Comme son nom l’indique ici il s’agit de la base de la poutre. Il s’agit d’un repère qui pouvant être assigné à une translation et/ou rotations désirée, et qui résultera d’une position finale. A noter, que le repère est toujours associé à un ressort afin d’être fixe dans le repère global de SOFA. + +$$ Rotation =[x , y, z] $$ + +$$ Translation = [x,y,z] $$ + +$$ Position = [x , y, z, xq, yq, zq, wq] $$ + +### Exemple - Base rigide + +![exemple rigid translation.png](images/exemple_rigid_translation.png) + +$$ Rotation =[0 , 0, 0] $$ + +$$ Translation = [0,1,0] $$ + +$$ Position = [0 , 1, 0, 0, 0, 0, 1] $$ + +### Section + +![noeud curv.png](images/noeud_curv.png) + +Les sections sont situées dans le repère local de Cosserat. Une section représente la distance entre deux nœuds : + +$$ L0 /L1 = Section 1 $$ + +$$ L1/L2 = Section 2 $$ + +Une cross-section est une partie de la poutre qu’on vient couper de manière transversale. De manière générale, on suppose que les cross sections sont rondes et ont le même rayon tout le long de la poutre. Mais il est possible que la forme de la poutre ne soit pas circulaire mais rectangulaire, et que le rayon change d’une distance à une autre. Les coordonnées des sections et des noeuds se retrouvent dans un tableau nommé “curv_abs_input” (:Curviligne abscisse inputs). + + + +Il est possible d’appliquer une déformation à partir d’un certain nœud, les deux déformations possibles sont la torsion (selon x), et la flexion (selon y ou z). + +$$ positionS = [x,y,z] $$ + +$$ Flexion = -+(1/LenghtSection) * pi $$ + +Pi : Angle de rotation + +(1/LengthSection) : Vecteur unitaire (normalisation) + +-/+ : Sens de rotation + +### Exemple - Section (1) + +Pour une poutre de longueur de 8cm avec un nombre de sections de 6 on a : + +![exemple curv abs input.png](images/exemple_curv_abs_input.png) + +**Tableau curv_abs_input :** + +![Untitled](images/Untitled.png) + +### Exemple - Section (2) + +Pour une poutre de longueur de 8cm avec un nombre de sections de 6 on a : + +![position 90degres.png](images/position_90degres.png) + +**Tableau curv_abs_input :** + +||X|Y|Z| +|---|---|---|---| +|0|0|0|0| +|1|0|0|0| +|2|0|0|0| +|3|0|0|0| +|4|0|0|0| +|5|0|0|-2.35| + +### Frame + +![frame1.png](images/frame1.png) + +La frame est représenté dans le repère locale de Cosserat, puis elle est intégrée dans le repère global de SOFA. Une frame est représentée comme les bases rigides, on retrouve les coordonnées de translation et rotation : + +$$ R :[x , y, z, 0, 0, 0, 1] $$ + +Les frames ne sont pas obligatoirement à équidistances les unes par rapport aux autres. Il est possible de concentrer un certain nombre de frames à un certain endroit, ce qui permet une rapidité de calcul sur l’endroit d’étude désirée. + + + +## Plugin Cosserat - SOFA + +### RigidBases + +- MechanicalObject + + - Coordonnées du système : + + $$ R :[x , y, z, 0, 0, 0, 1] $$ + +- Spring + + - Rigidité + - Rigidité angulaire + +### CosseratCoordinate + +- MechanicalObject + - Nombre de sections + - Taille totale de la poutre +- BeamHookLaw + - Forme de la cross-section + - Taille de la section + - Rayon + +### CosseratFrame + +- MechanicalObject + - Nombre de frame + - Taille totale de la poutre +- CosseratMapping + - MechanicalObject de RigidBases + - MechanicalObject de Cosserat Coordinate + - Curv in + - Curv out \ No newline at end of file diff --git a/docs/text/cosserat_tutorial.md b/docs/text/cosserat_tutorial.md new file mode 120000 index 00000000..c8e94902 --- /dev/null +++ b/docs/text/cosserat_tutorial.md @@ -0,0 +1 @@ +/Users/yadagolo/travail/plugin/plugin.Cosserat/examples/python3/tutorial/tutorial.md \ No newline at end of file diff --git a/docs/text/tutorial.md b/docs/text/tutorial.md new file mode 100644 index 00000000..6732d91c --- /dev/null +++ b/docs/text/tutorial.md @@ -0,0 +1,104 @@ +--- +title: DCM-FEM for Soft-Robot modeling Tutorial +tags: + - tutorial +Audience: Researchers, engineers, and students interested in soft robotics and the simulation of deformable robots. +Duration: This tutorial can vary in duration based on the depth and complexity of the material, but a typical plan could span 2-4 hours. +Prerequisites: Participants should have a basic understanding of robotics, mechanics, and computer simulations. Knowledge of finite element methods (FEM) and rigid body dynamics can be helpful. +cssclasses: + - dashboard +--- + +_Welcome to this tutorial on SOFA-Cosserat Plugin._ + +_Outline of what participants can expect to learn during this tutorial ?_ + +[Formation plugin : Cosserat - CodiMD](https://notes.inria.fr/gcfuFPDYSeeAlG4gzfDJwA#) + +--- +# Tutorial Roadmap + +- What to Expect ? + - Provide an overview of the tutorial's structure. + - Sections and topics we'll cover during the tutorial. +- Ask questions and be actively engage throughout this tutorial + - The first time I am doing this, so I really need your feedback + +--- + +## [Introduction](Introduction.md) + +- 🗄️Briefly introduce the field of soft robotics +- The motivation for combining FEM and DCM models. + +--- +## [Background Concepts](Background%20Concepts.md) +- An overview of Discrete Cosserat Model (DCM) and their relevance in soft robotics. +- Finite Element Methods (FEM) and their use in simulating deformable structures ? +- The concept of compliance matrices and their role in soft robot modeling ? + +--- + +## [Setting up the Environment](Setting%20up%20the%20Environment.md) +- The software tools and libraries used (SOFA, **Cosserat** plugin). +- Instructions for setting up the simulation environment. +- [cosserat_python_scene](cosserat_python_scene.md) + +--- +## [Direct Simulation](Direct%20Simulation.md) + - How to + - Build the DCM scene ? + - Integrate it with FEM for the soft body ? + - The direct simulation of a soft robot (e.g., the gripper example from the paper). + - The role of constraints, friction, and contact forces. + +--- + +## [Inverse Simulation](Inverse%20Simulation.md) + - Demonstrate an inverse simulation for soft robots (e.g., using the soft finger or tentacle as examples). + - Explain how to compute actuation values to achieve desired end-effector positions. + - Discuss the handling of sliding constraints in the inverse problem. + +--- + +## [Model Convergence and Sensitivity Analysis](Model%20Convergence%20and%20Sensitivity%20Analysis.md) + - Here we will share insights on how to evaluate the convergence of your model with varying parameters + - e.g., number of sections defining a cable + - Discuss sensitivity to material properties and other simulation parameters. + +--- + +## [Advanced Topics and Future Work](Advanced%20Topics%20and%20Future%20Work.md) + - Explore potential applications of your method in soft robot design. + - Discuss the ongoing and future research in this field, including real-world experiments and stress validation on cables. + +--- + +## **8. Performance Optimization** + - How to **optimize the computation speed**, potentially using **parallelization**, model **order reduction**, or **recursive algorithms** for DCM. + +--- + +## **9. Conclusion and Q&A** + - Summarize key takeaways from the tutorial. + - Open the floor for questions and discussions. + +--- + +## **10. Practical Hands-On Session (Optional)** + - If feasible, you can provide participants with exercises or hands-on practice to apply the concepts learned. + +--- + +## 11. **Materials:** +- Presentation slides (see GitHub Repo) +- Repo folder tutorials. +- Code examples and simulations on the Repo/example. +- Reference: + - Paper RAL-SoRo : + - Paper (Féderico) : + - Paper (Flavie) : +- Q&A session for participant engagement. +- Feedback : direct and mails + +--- \ No newline at end of file diff --git a/examples/python3/__init__.py b/examples/python3/__init__.py index f079f1ef..9dcf5866 100644 --- a/examples/python3/__init__.py +++ b/examples/python3/__init__.py @@ -13,4 +13,4 @@ """ -__all__ = ["cosserat","useful", "actuators"] +__all__ = ["cosserat", "useful", "actuators"] diff --git a/examples/python3/tutorial/tutorial.md b/examples/python3/tutorial/tutorial.md index 80b5897c..18741b1a 100644 --- a/examples/python3/tutorial/tutorial.md +++ b/examples/python3/tutorial/tutorial.md @@ -1,33 +1,14 @@ -### Mathematical Description of Cosserat Rods - - -### Reference Frames - -### Conservation of Momentum - -### Linear Elasticity - - -## Numerics - -### Spatial Discretization - -### Time Discretization - -### Reduce to Global State - -### Global to Reduce State - -### Boundary conditions and interaction forces +A step-by-step tutorial for understanding how to model a 1D object using the Cosserat plugin within the SOFA framework. +## Modeling 1D Objects with Cosserat Theory in SOFA** +[Theory](Theory.md) +[Numerics](docs/text/Numerics.md) -A step-by-step tutorial for understanding how to model a 1D object using the Cosserat plugin within the SOFA framework. -# Modeling 1D Objects with Cosserat Theory in SOFA** **Introduction:** In this tutorial, we will learn how to create a 1D object model using Cosserat Theory within the SOFA framework. This model is useful for simulating various physical systems, such as beams or rods. We'll cover the essential components and parameters needed to set up the model. diff --git a/examples/python3/useful/header.py b/examples/python3/useful/header.py index 67bcc966..65ad55fa 100644 --- a/examples/python3/useful/header.py +++ b/examples/python3/useful/header.py @@ -58,7 +58,9 @@ def addHeader(parentNode, multithreading=False, inverse=False, isConstrained=Fal "Sofa.GL.Component.Rendering3D", # Needed to use components OglGrid, OglModel "Sofa.GUI.Component", "Sofa.Component.Collision.Geometry", "Sofa.Component.LinearSolver.Direct", "Sofa.Component.Mapping.Linear", "Sofa.Component.MechanicalLoad", - "Sofa.Component.StateContainer", 'Sofa.Component.ODESolver.Backward' + 'Sofa.Component.Engine.Select', 'Sofa.Component.SolidMechanics.FEM.Elastic', + "Sofa.Component.StateContainer", 'Sofa.Component.ODESolver.Backward', + 'Sofa.Component.SolidMechanics.FEM.HyperElastic' ]) settings.addObject('BackgroundSetting', color=[1, 1, 1, 1]) @@ -129,7 +131,6 @@ def addSolverNode(node, name='solverNode', template='CompressedRowSparseMatrixd' solverNode = node.addChild(name) solverNode.addObject('EulerImplicitSolver', firstOrder=firstOrder, rayleighStiffness=rayleighStiffness, rayleighMass=rayleighMass) - solverNode.addObject('GenericConstraintSolver', tolerance=1e-5, maxIterations=5e2) if iterative: solverNode.addObject('CGLinearSolver', name='Solver', template=template) else: diff --git a/src/Cosserat/constraint/CosseratNeedleSlidingConstraint.h b/src/Cosserat/constraint/CosseratNeedleSlidingConstraint.h index fef8e2d3..ce2663af 100644 --- a/src/Cosserat/constraint/CosseratNeedleSlidingConstraint.h +++ b/src/Cosserat/constraint/CosseratNeedleSlidingConstraint.h @@ -109,7 +109,7 @@ namespace sofa::component::constraintset j.multTransposeBaseVector(res, lambda); // lambda is a vector of scalar value so block size is one. } - void storeLambda(const ConstraintParams */*cParams*/, MultiVecDerivId res, const sofa::linearalgebra::BaseVector *lambda) override + void storeLambda(const ConstraintParams */*cParams*/, MultiVecDerivId /*res*/, const sofa::linearalgebra::BaseVector */*lambda*/) override { // if (cParams) // { diff --git a/src/Cosserat/constraint/QPSlidingConstraint.inl b/src/Cosserat/constraint/QPSlidingConstraint.inl index 3defedf8..d45b7a34 100644 --- a/src/Cosserat/constraint/QPSlidingConstraint.inl +++ b/src/Cosserat/constraint/QPSlidingConstraint.inl @@ -206,7 +206,7 @@ void QPSlidingConstraint::getConstraintResolution(const ConstraintPar { ReadAccessor> positions = m_state->readPositions(); // std::cout << "The position size is : " << positions.size()<< std::endl; - double imposedValue= 1.0; + // double imposedValue = 1.0; for (size_t i = 0; i < positions.size(); i++){ resTab[offset++] = new BilateralConstraintResolution(); @@ -220,7 +220,7 @@ void QPSlidingConstraint::getConstraintResolution(const ConstraintPar template -void QPSlidingConstraint::draw(const VisualParams* vparams) +void QPSlidingConstraint::draw(const VisualParams* /*vparams*/) { if(d_componentState.getValue() != ComponentState::Valid) return ; diff --git a/src/Cosserat/engine/PointsManager.h b/src/Cosserat/engine/PointsManager.h index 4ebcc49b..6d9f7353 100755 --- a/src/Cosserat/engine/PointsManager.h +++ b/src/Cosserat/engine/PointsManager.h @@ -43,8 +43,8 @@ namespace sofa::core::behavior PointSetTopologyModifier *m_modifier; core::behavior::MechanicalState *m_beam; - void init(); - void handleEvent(sofa::core::objectmodel::Event *event); + void init() override; + void handleEvent(sofa::core::objectmodel::Event *event) override; // void draw(const core::visual::VisualParams *vparams); void addNewPointToState(); diff --git a/src/Cosserat/engine/PointsManager.inl b/src/Cosserat/engine/PointsManager.inl index 71754de8..50c03e08 100755 --- a/src/Cosserat/engine/PointsManager.inl +++ b/src/Cosserat/engine/PointsManager.inl @@ -74,10 +74,9 @@ namespace sofa::core::behavior { helper::WriteAccessor> x = *this->getMstate()->write(core::VecCoordId::position()); helper::WriteAccessor> xfree = *this->getMstate()->write(core::VecCoordId::freePosition()); - const helper::ReadAccessor> &beam = m_beam->readPositions(); + unsigned nbPoints = this->getTopology()->getNbPoints(); // do not take the last point because there is a bug - size_t beamSz = beam.size(); sofa::type::vector Indices; if (nbPoints > 0) { diff --git a/src/Cosserat/forcefield/BeamHookeLawForceField.inl b/src/Cosserat/forcefield/BeamHookeLawForceField.inl index 5acf74a9..4efb7588 100644 --- a/src/Cosserat/forcefield/BeamHookeLawForceField.inl +++ b/src/Cosserat/forcefield/BeamHookeLawForceField.inl @@ -93,45 +93,60 @@ namespace sofa::component::forcefield reinit(); } + /*Cross-Section Properties Initialization: The reinit function begins by recalculating the properties + related to the cross-section of the beams. It calculates the area moment of inertia (Iy and Iz), + the polar moment of inertia (J), and the cross-sectional area (A). + These calculations depend on the chosen cross-section shape, either circular or rectangular. T + he formulas used for these calculations are based on standard equations for these properties.*/ template void BeamHookeLawForceField::reinit() { - Real Iy, Iz, J; - Real A; - if ( d_crossSectionShape.getValue().getSelectedItem() == "rectangular" ) + // Precompute and store values + Real Iy, Iz, J, A; + if ( d_crossSectionShape.getValue().getSelectedItem() == "rectangular") //rectangular cross-section { Real Ly = d_lengthY.getValue(); Real Lz = d_lengthZ.getValue(); - Iy=Ly*Lz*Lz*Lz/12.0; - Iz=Lz*Ly*Ly*Ly/12.0; - J=Iy + Iz; - A = Ly*Lz; + const Real LyLzLzLz = Ly * Lz * Lz * Lz; + const Real LzLyLyLy = Lz * Ly * Ly * Ly; + + Iy = LyLzLzLz / 12.0; + Iz = LzLyLyLy / 12.0; + J = Iy + Iz; + A = Ly * Lz; } - else //circular section + else //circular cross-section { msg_info() << "Cross section shape." << d_crossSectionShape.getValue().getSelectedItem() ; Real r = d_radius.getValue(); Real rInner = d_innerRadius.getValue(); - Iz = M_PI*(r*r*r*r - rInner*rInner*rInner*rInner)/4.0; - Iy = Iz ; - J = Iz + Iy; - A = M_PI*(r*r - rInner*rInner); + const Real r4 = r * r * r * r; + const Real rInner4 = rInner * rInner * rInner * rInner; + + Iy = M_PI * (r4 - rInner4) / 4.0; + Iz = Iy; + J = Iy + Iz; + A = M_PI * (r * r - rInner4); } m_crossSectionArea = A; - if(!d_variantSections.getValue()){ - if(!d_useInertiaParams.getValue()){ - Real E= d_youngModulus.getValue(); - Real G= E/(2.0*(1.0+d_poissonRatio.getValue())); + if(!d_variantSections.getValue()) + { + if(!d_useInertiaParams.getValue()) + { + Real E = d_youngModulus.getValue(); + Real G = E/(2.0*(1.0+d_poissonRatio.getValue())); m_K_section[0][0] = G*J; m_K_section[1][1] = E*Iy; m_K_section[2][2] = E*Iz; - } else{ + } + else + { msg_info("BeamHookeLawForceField")<< "Pre-calculated inertia parameters are used for the computation " "of the stiffness matrix."; m_K_section[0][0] = d_GI.getValue(); @@ -140,22 +155,31 @@ namespace sofa::component::forcefield } }else { + /*If the d_variantSections flag is set to true, it implies that multi-section beams are used for + the simulation. In this case, the code calculates and initializes a list of stiffness matrices + (m_K_sectionList) for each section. The properties of each section, such as Young's modulus and + Poisson's ratio, are specified in the d_youngModulusList and d_poissonRatioList data.*/ msg_info("BeamHookeLawForceField")<< "Multi section beam are used for the simulation!"; m_K_sectionList.clear(); - size_t szYM = d_youngModulusList.getValue().size(); - size_t szPR = d_poissonRatioList.getValue().size(); - size_t szL = d_length.getValue().size(); + + const size_t szL = d_length.getValue().size(); - if((szL != szPR)||(szL != szYM)){ + if((szL != d_poissonRatioList.getValue().size())||(szL != d_youngModulusList.getValue().size())){ msg_error("BeamHookeLawForceField")<< "Please the size of the data length, youngModulusList and " "poissonRatioList should be the same !"; return; } - for(size_t k=0; k + template void BeamHookeLawForceField::addDForce(const MechanicalParams* mparams, DataVecDeriv& d_df , const DataVecDeriv& d_dx) diff --git a/src/Cosserat/mapping/BaseCosserat.inl b/src/Cosserat/mapping/BaseCosserat.inl index c43bf5c4..f8ec5a2d 100644 --- a/src/Cosserat/mapping/BaseCosserat.inl +++ b/src/Cosserat/mapping/BaseCosserat.inl @@ -389,7 +389,7 @@ void BaseCosserat::initialize() for (size_t i=0; i < sz; i++) { if (curv_abs_section[input_index] > curv_abs_frames[i]) { m_indicesVectors.push_back(input_index); - m_indicesVectorsDraw.push_back(input_index); + m_indicesVectorsDraw.push_back(input_index); // maybe I shouldn't do this here !!! } else if(curv_abs_section[input_index] == curv_abs_frames[i]){ m_indicesVectors.push_back(input_index); diff --git a/src/Cosserat/mapping/DiscreteCosseratMapping.inl b/src/Cosserat/mapping/DiscreteCosseratMapping.inl index 9c94458e..d89c3fb9 100644 --- a/src/Cosserat/mapping/DiscreteCosseratMapping.inl +++ b/src/Cosserat/mapping/DiscreteCosseratMapping.inl @@ -50,14 +50,10 @@ DiscreteCosseratMapping::DiscreteCosseratMapping() : m_fromModel1(NULL) , m_fromModel2(NULL) , m_toModel(NULL) - , d_deformationAxis(initData(&d_deformationAxis, (int)1, "deformationAxis", - "the axis in which we want to show the deformation.\n")) - , d_max(initData(&d_max, (Real2)1.0e-2, "max", - "the maximum of the deformation.\n")) - , d_min(initData(&d_min, (Real2)0.0, "min", - "the minimum of the deformation.\n")) - , d_radius(initData(&d_radius, (Real2)0.05, "radius", - "the axis in which we want to show the deformation.\n")) + , d_deformationAxis(initData(&d_deformationAxis, (int)1, "deformationAxis", "the axis in which we want to show the deformation.\n")) + , d_max(initData(&d_max, (Real2)1.0e-2, "max", "the maximum of the deformation.\n")) + , d_min(initData(&d_min, (Real2)0.0, "min", "the minimum of the deformation.\n")) + , d_radius(initData(&d_radius, (Real2)0.05, "radius", "the axis in which we want to show the deformation.\n")) , d_drawMapBeam(initData(&d_drawMapBeam, true,"nonColored", "if this parameter is false, you draw the beam with " "color according to the force apply to each beam")) , d_color(initData(&d_color, type::Vec4f (40/255.0, 104/255.0, 137/255.0, 0.8) ,"color", "The default beam color")) @@ -362,7 +358,7 @@ void DiscreteCosseratMapping:: applyJT( dataVecOut2Force[0]->endEdit(); } -//___________________________________________________________________________ + template void DiscreteCosseratMapping::applyJT( const core::ConstraintParams*/*cparams*/ , const type::vector< In1DataMatrixDeriv*>& dataMatOut1Const,