Home › Forum › SoftRobots › Using SoftRobots › How to control cable length in cable-driven manipulator
Tagged: Cable, cable driven, cable lenght, flexible manipulator, SOFA_2012, softrobots, Windows_10
- This topic has 5 replies, 3 voices, and was last updated 3 years, 3 months ago by Hugo.
-
AuthorPosts
-
13 May 2021 at 16:25 #19437DiogoBlocked
Hello everyone
I’m trying to simulate a flexible manipulator that consists of a cilindrical tube actuated by 3 equidistant cables, passing through channels from bottom to top. So far, I’ve used the SofaPythonController setup that is very similar the CableGripper tutorial included in the plugin documentation. I’ve successfully implemented the 3 cables, but I cannot seem to be able to control the cable length directly. The tutorial is setup for “displacement”, but if I add one unit to each of the cables, the vertical coordinate of a point on top of the manipulator does not change by one centimeter, it changes by around 0.9 cm (the unit I’m using).
My question is how is the displacement measured, and if there is a way to just work with cable length, since that would make validating the results from theoritical models a little easier.
As I said, my setup is essentially the same as one finger in the CableGripper, I just added two other cables, but if my code is required then I’d be more than happy to share.
Thank you in advance for the amazing software and plugin, and I’m fully available for any further questions!
Windows 10/Sofa v20.12 (binary with SoftRobots pre-installed)
18 May 2021 at 11:27 #19469AryaBlockedHello @c4rs200, I have worked on a very similar bot with 3 cable actuators. I would love to see your code to solve your problem better, I assume you are manipulating the length of the cable actuator by changing the
CableConstraint
value. You can considerCableConstraint
as the value of your Cable length since the value ofCableConstraint
is basically derived from it being a mechanical object withindices=range(len(cableGeometry))
.Note that all changes to be made to your
CableConstraint.value
need to be made in a function within theSofa.PythonScriptController
for them to reflect in your simulation dynamically.Cheers!
18 May 2021 at 15:59 #19475DiogoBlockedHello @aryakarani
Thank you so much for your answer!! This is my current code:
# -*- coding: utf-8 -*- from stlib.physics.deformable import ElasticMaterialObject from stlib.physics.constraints import FixedBox from stlib.scene import Node from softrobots.actuators import PullingCable from splib.loaders import loadPointListFromFile import Sofa import os #Opening the file file1 = open("myfile.txt","w") #Defining the python controller class CilinderController(Sofa.PythonScriptController): def __init__(self, node, cable1, cable2, cable3): self.node=node self.cableconstraintvalue1 = cable1.getObject("CableConstraint").findData('value') self.cableconstraintvalue2 = cable2.getObject("CableConstraint").findData('value') self.cableconstraintvalue3 = cable3.getObject("CableConstraint").findData('value') self.cableconstraintdisp1 = cable1.getObject("CableConstraint").findData('displacement') self.cableconstraintdisp2 = cable2.getObject("CableConstraint").findData('displacement') self.cableconstraintdisp3 = cable3.getObject("CableConstraint").findData('displacement') self.name = "CilinderController" self.n=1 self.deformableObject = self.node.ElasticMaterialObject #Control actions for each cable (extend and retract) def onKeyPressed(self,c): if (c == "4"): self.cableconstraintvalue1.value = self.cableconstraintvalue1.value[0][0] + 1. if (c == "1"): self.cableconstraintvalue1.value = self.cableconstraintvalue1.value[0][0] - 1. if (c == "5"): self.cableconstraintvalue2.value = self.cableconstraintvalue2.value[0][0] + 1. if (c == "2"): self.cableconstraintvalue2.value = self.cableconstraintvalue2.value[0][0] - 1. if (c == "6"): self.cableconstraintvalue3.value = self.cableconstraintvalue3.value[0][0] + 1. if (c == "3"): self.cableconstraintvalue3.value = self.cableconstraintvalue3.value[0][0] - 1. if (c == "9"): #file1.write(str(Output1)) self.node.getRootContext().animate = False file1.close() #Writing the displacements and point position to a file def onEndAnimationStep(self,dt): # displacement1 = self.cableconstraintdisp1.value # displacement2 = self.cableconstraintdisp2.value # displacement3 = self.cableconstraintdisp3.value displacement1 = self.cableconstraintvalue1.value displacement2 = self.cableconstraintvalue2.value displacement3 = self.cableconstraintvalue3.value # dispform1 = "{:.2f}".format(displacement1) # dispform2 = "{:.2f}".format(displacement2) # dispform3 = "{:.2f}".format(displacement3) dispform1 = displacement1 dispform2 = displacement2 dispform3 = displacement3 position=self.deformableObject.dofs.getData("position").value positionform1="{:.2f}".format(float(position[493][0])) positionform2="{:.2f}".format(float(position[493][1])) positionform3="{:.2f}".format(float(position[493][2])) file1.write(str(self.n) + ',' + str(dispform1) + ","+ str(dispform2) + "," + str(dispform3) + ", ["+ str(positionform1) + ";" + str(positionform2) + ";" + str(positionform3)+"]"+'\n') self.n +=1 def Cilinder(parentNode=None, name="Cilinder", rotation=[0.0, 0.0, 0.0], translation=[0.0, 0.0, 0.0], fixingBox=[0.0,0.0,0.0], pullPointLocation=[0.0,0.0,0.0]): #Defining the elastic material cilinder = Node(parentNode, "Cilinder") eobject = ElasticMaterialObject(cilinder, volumeMeshFileName="data/mesh/Elo3D.vtk", poissonRatio=0.49, youngModulus=48000000, totalMass=1.5, surfaceColor=[0.0, 0.8, 0.7], surfaceMeshFileName="data/mesh/EloSurface.stl") FixedBox(eobject, doVisualization=True, atPositions=[-30, 0 ,-30 ,30 ,5,30]) #Creating the cables cable1 = PullingCable(eobject, cableGeometry=loadPointListFromFile("data/mesh/cable1S.json")) cable2 = PullingCable(eobject, cableGeometry=loadPointListFromFile("data/mesh/cable2S.json")) cable3 = PullingCable(eobject, cableGeometry=loadPointListFromFile("data/mesh/cable3S.json")) #Calling the controller CilinderController(cilinder,cable1,cable2,cable3)
This is the relevant part, the rest is just defining the scene. As you can see, my goal is to get the cable lengths and the position of a point to a file. What happens right now is that the displacements show up as zero when the robot is at rest (the cable length at rest is meant to be 84.63 cm) and when I give inputs, it changes to “1” or “-1” etc, according to the given input.
There are other ways to define the cables, maybe that’s the issue? The cable geometry files are just a list of points through where the cables pass in the channels inside the robot
11 June 2021 at 10:43 #19670HugoKeymasterAny success @c4rs200, following @aryakarani advices?
I must say, these constraints being part of the SoftRobot plugin, I am not super familiar with it. But keep us udpated 😉
Hugo
16 June 2021 at 16:21 #19713DiogoBlockedHi @hugo
I had to put the work on hold because of exams, but I’ve now returned and I’m still trying to figure things. I think me and @aryakarani have different implementations of the CableConstraint, since I think I used an old one that came with an older version of the SoftRobots plugin that is not the same as newer documentation shows, so I’m working around that, but thank you for checking in! I will update the thread if I am sucessful in order to help other people with the same problem
Best wishes,
Diogo
30 July 2021 at 11:41 #20102 -
AuthorPosts
- You must be logged in to reply to this topic.