diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e166de2..32e583b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -62,16 +62,28 @@ jobs: ccache -s fi + - name: Sanitize artifact name + id: sanitize + # This step removes special characters from the artifact name to ensure compatibility with upload-artifact + # Characters removed: " : < > | * ? \r \n \ / + # Spaces are replaced with underscores + # This sanitization prevents errors in artifact creation and retrieval + shell: pwsh + run: | + $originalName = "Cosserat_${{ steps.sofa.outputs.run_branch }}_for-SOFA-${{ steps.sofa.outputs.sofa_version }}_${{ runner.os }}" + $artifact_name = $originalName -replace '[":;<>|*?\r\n\\/]', '' -replace ' ', '_' + echo "artifact_name=$artifact_name" >> $env:GITHUB_OUTPUT + - name: Create artifact - uses: actions/upload-artifact@v2.2.4 + uses: actions/upload-artifact@v4.4.0 with: - name: CosseratPlugin_${{ steps.sofa.outputs.run_branch }}_for-SOFA-${{ steps.sofa.outputs.sofa_version }}_${{ runner.os }} + name: ${{ steps.sanitize.outputs.artifact_name }} path: ${{ env.WORKSPACE_INSTALL_PATH }} - name: Install artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4.1.7 with: - name: CosseratPlugin_${{ steps.sofa.outputs.run_branch }}_for-SOFA-${{ steps.sofa.outputs.sofa_version }}_${{ runner.os }} + name: ${{ steps.sanitize.outputs.artifact_name }} path: ${{ env.WORKSPACE_ARTIFACT_PATH }} # - name: Set env vars for tests @@ -119,7 +131,7 @@ jobs: continue-on-error: true steps: - name: Get artifacts - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4.1.7 with: path: artifacts @@ -138,6 +150,6 @@ jobs: fail_on_unmatched_files: false target_commitish: ${{ github.sha }} files: | - artifacts/CosseratPlugin_*_Linux.zip - artifacts/CosseratPlugin_*_Windows.zip - artifacts/CosseratPlugin_*_macOS.zip + artifacts/Cosserat_*_Linux.zip + artifacts/Cosserat_*_Windows.zip + artifacts/Cosserat_*_macOS.zip diff --git a/README.md b/README.md index 7afb195..166478d 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,9 @@ In contrast, many other models in continuum media mechanics tend to treat materi 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. -Go into theorotical part of the plugin [Theory](docs/text/Theory.md) +Go into theorotical part of the plugin [Theory](examples/python3/tutorial/Writerside/topics/Theory.mdexamples/python3/tutorial/Writerside/topics/Theory.md) -Follow the tutorial : [cosserat_tutorial](docs/text/cosserat_tutorial.md) +Follow the tutorial : [cosserat_tutorial](tutorial/text/cosserat_tutorial.md) ## Some use cases @@ -40,7 +40,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i | View 1 | View 2 | View 3 | |----------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------| -| ![333](docs/images/multiSectionWithColorMap1.png) | ![333](docs/images/multiSectionWithColorMap2.png) | ![333](docs/images/multiSectionWithColorMap3.png) | +| ![333](tutorial/images/multiSectionWithColorMap1.png) | ![333](tutorial/images/multiSectionWithColorMap2.png) | ![333](tutorial/images/multiSectionWithColorMap3.png) | ## Utilizing the Discrete Cosserat Model for Cable Modeling in Deformable Robot Control: @@ -48,19 +48,19 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i | Direct simulation of a soft gripper | The study of the model convergence | |-------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------| -| ![400](docs/images/cosseratgripper_2.png) | ![400](../../../../Templater/images/tenCossseratSections.png.md) | +| ![400](tutorial/images/cosseratgripper_2.png) | ![400](tutorial/images/tenCossseratSections.png) | --- Actuation -| | | | +| | | | |---------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------:|--------------------------------------------------------------------------------------------------------:| | DCM Beam actuation using a cable ```d =``` | DCM Beam actuation using a cable ```d =``` | Beam actuation using a cable ```d =``` | -| | | | +| | | | |----------------------------------------------------------------------------|:-------------------------------------------------------------------------:|----------------------------------------------------------------------------:| | DCM Beam actuation using a cable ```d =``` | DCM Beam actuation using a cable ```d =``` | Beam actuation using a cable ```d =``` | @@ -124,21 +124,21 @@ with a constant cross-section. | View 1 | View 2 | View 3 | |---------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------| -| | | | +| | | | ### DCM for cable modeling to control deformable robots: | Direct simulation of a soft gripper | The study the model convergence | |------------------------------------------------------------------------------------------| --- | -| | | +| | | ### Some use cases -| | | | +| | | | | ------------- |:-------------:| -----:| | DCM Beam actuation using a cable ```d =``` | DCM Beam actuation using a cable ```d =```| Beam actuation using a cable ```d =```| -| | | | +| | | | | ------------- |:-------------:| -------------:| | DCM Beam actuation using a cable ```d =``` | DCM Beam actuation using a cable ```d =```| Beam actuation using a cable ```d =```| diff --git a/examples/python3/PCS_Example1.py b/examples/python3/PCS_Example1.py index d8ab7dc..221361b 100644 --- a/examples/python3/PCS_Example1.py +++ b/examples/python3/PCS_Example1.py @@ -52,19 +52,17 @@ def __init__(self, *args, **kwargs): def onAnimateEndEvent(self, event): if self.applyForce: - with self.forceNode.force.writeable() as force: - vec = [0., 0., 0., 0., (self.forceCoeff * 1.) / - sqrt(2), (self.forceCoeff * 1.) / sqrt(2)] - for i, v in enumerate(vec): - force[i] = v + with self.forceNode.forces.writeable() as force: + force[0] = [0., 0., 0., 0., self.forceCoeff/sqrt(2.), self.forceCoeff/sqrt(2.)] + def onKeypressedEvent(self, event): key = event['key'] if key == "+": - self.forceCoeff += 1 + self.forceCoeff += 0.1 print(f' The new force coeff is : {self.forceCoeff}') elif key == "-": - self.forceCoeff -= 1 + self.forceCoeff -= 0.1 print(f' The new force coeff is : {self.forceCoeff}') @@ -93,7 +91,7 @@ def createScene(rootNode): beamFrame = PCS_Cosserat.cosseratFrame constForce = beamFrame.addObject('ConstantForceField', name='constForce', showArrowSize=1.e-8, - indices=nonLinearConfig['nbFramesF'], force=F1) + indices=nonLinearConfig['nbFramesF'], forces=F1) solverNode.addObject(ForceController( parent=solverNode, cosseratFrames=beamFrame.FramesMO, forceNode=constForce)) diff --git a/examples/python3/cosserat/cosseratObject.py b/examples/python3/cosserat/cosseratObject.py index c58b374..cae788e 100644 --- a/examples/python3/cosserat/cosseratObject.py +++ b/examples/python3/cosserat/cosseratObject.py @@ -12,6 +12,8 @@ import Sofa from cosserat.usefulFunctions import buildEdges, pluginList, BuildCosseratGeometry from useful.utils import addEdgeCollision, addPointsCollision +import warnings + cosserat_config = { "init_pos": [0.0, 0.0, 0.0], @@ -133,6 +135,17 @@ def __init__(self, *args, **kwargs): "radius", ) + print ('===============>DEPRECATED<============================\n') + + warnings.warn( + "\n====> DEPRECATED: This prefab CosseratObject class will be removed in a future version. " + "Use CosseratBase instead. For examples and tutorials, please refer to " + "the 'tutorial' folder located at plugin.Cosserat/tutoria/tuto_scenes .\n" + ) + print("========================> DEPRECATED<============================\n") + + + if self.parent.hasObject("EulerImplicitSolver") is False: print("The code does not have parent EulerImplicite") self.solverNode = self.addSolverNode() @@ -215,10 +228,11 @@ def addRigidBaseNode(self): rigidBaseNode = self.addChild("rigidBase") # trans = [t for t in self.translation.value] - trans = list(self.translation.value) - rot = list(self.rotation.value) + trans = self.translation.value + rot = self.rotation.value + # @todo converter - positions = [list(pos) for pos in self.position.value] + positions = [pos for pos in self.position.value] rigidBaseNode.addObject( "MechanicalObject", @@ -382,7 +396,7 @@ def createScene(rootNode): name="constForce", showArrowSize=1.0e-2, indices=12, - force=[0.0, -100.0, 0.0, 0.0, 0.0, 0.0], + forces=[0.0, -100.0, 0.0, 0.0, 0.0, 0.0], ) return rootNode