Forum Replies Created
-
AuthorPosts
-
6 February 2019 at 16:08 in reply to: [SOLVED] Harmonic excitation with constantForceField (Python Controller) #13005Damien MarchalBlocked
Hi Nassim,
For what you want to do I can see two approach.
The first one is to implement your own controller to manipulate the data field at each animation step.import Sofa import math class MyController(Sofa.PythonScriptController): def __init__(self, node, dofs): '''With SofaPython it is mandatory to pass at least one argument that is the node. not doing that will crash Sofa ''' self.dofs = dofs self.currentTime = 0.0 self.scaleFactor = 10.0 def onBeginAnimationStep(self, dt): '''This method is called automatically by Sofa at each timestep''' self.currentTime += dt force = self.dofs.findData('position').value force[0][0] = math.cos((self.currentTime*self.scaleFactor*math.pi)/180) force[0][1] = math.sin((self.currentTime*self.scaleFactor*math.pi)/180) self.dofs.findData('position').value = force def createScene(rootNode): '''Move an object in real-time by reading new values from a python file''' v = rootNode.createObject("MechanicalObject", name="dofs", position=[0.0,0.0,0.0]) v.showObject = True v.showObjectScale = 10.0 MyController(rootNode, v)
The other rely on the STLIB which feature an animation package, it would look like that:
# coding: utf-8 # splib is available here: https://github.com/SofaDefrost/STLIB import splib import math ## This function is called by the animation manager at each timestep, the factor ## is updated to indicate how much has progress the animation. ## The factor is between [0, 1] 0 is the begin of the animation, 1 is the end. def harmonicAnimation(target, factor, scaleFactor): t = [ math.cos((factor*scaleFactor*math.pi)/180), 0, math.sin((factor*scaleFactor*math.pi)/180)] print("I'm updating the position using: ", factor, " new pos is", t) target.position = t def createScene(rootNode): from splib.animation import animate, AnimationManager ## This will create a single AnimationManager python script controller that will animate all the ## animation on the scene. AnimationManager(rootNode) # The object t = rootNode.createObject("MechanicalObject", position=[0,0,0]) t.showObject=True t.showObjectScale=10 # This fire up an animation, # The movement is computed using the "myanimate" function # The target of the animation is the 't' object # This animation will have 0.5 second duration (simulation time) # 'ping-pong' means that the animation will repeat to-from. animate(harmonicAnimation, {"target" : t, "scaleFactor" : 1.0}, duration=1.0, mode="pingpong" )
Tell us if you succeed.
Damien.Damien MarchalBlockedHi Daryna, hi Pierre,
I’m looking in the code base right now.
And I wonder if you are sure of the file you were using ?
By reading the Sofa source code I noticed several things:
Whatever Xsp 3.0 or 4.0 to specify the number of springs & masses it is neede to use these keywords:Xsp 3.0 numm 2 nums 3 ...
Then with Xsp 3.0 format the expected format is:
lspg 1 45 19 100.000000 0.100000 -1.000000
But with Xsp 4.0 you have more parameters like that:
lspg 1 45 19 100.000000 0.100000 -1.000000 0.0 0.0 0.0
I don’t know a lot about Xsp so I wonder if the code base (or the file format) has changed since last time you use it or if you made a mistake in your Xsp file.
Do you have any ideas ?
Damien.
Damien MarchalBlockedDear Fatima.
Using TCP/IP is fine but there is more easy to use protocols. In our team when we want to exchange data that way we are using zeromq (http://zeromq.org/) or OSC (http://opensoundcontrol.org/introduction-osc) because they have good python binding and thus work very well with Sofa. But i ignore if there is way to use that in matlab, a quick search on a search engine seems to say so: (eg: https://www.qwant.com/?q=matlab%20zeromq&t=web)
Hope this helps
Regards,
DamienDamien MarchalBlockedHello,
Thanks for the details.
To me this is a very strange behavior.Some extra questions:
– which compiler version are you using ?
– did you installed metis yourself, would it be possible that there is a version mismatch between the library you link against and the sofa build ?Damien
Damien MarchalBlockedHello Fatima,
The solution I’m proposing is to initialize the object during the creation of the simulated scene.
If you want to interactively change the position of the MechanicalObject
you need to use a PythonScriptController. This PythonScriptController will at each frame update the position of the sofa object using data coming from an external source (a file, a ros topic, a zeromq message, whatever).To give you an idea it would look like the following:
import json import Sofa class MyController(Sofa.PythonScriptController): def __init__(self, node, dofs): '''With SofaPython it is mandatory to pass at least one argument that is the node. not doing that will crash Sofa ''' self.dofs = dofs def onBeginAnimationStep(self, dt): '''This method is called automatically by Sofa at each timestep''' data = json.load(open("file.json")) self.dofs.position = data["values"] def createScene(rootNode): '''Move an object in real-time by reading new values from a python file''' data = json.load(open("file.json")) v = rootNode.createObject("MechanicalObject", name="dofs", position=data["values"]) v.showObject = True v.showObjectScale = 10.0 MyController(rootNode, v)
Damien
NB: updating position that w29 January 2019 at 13:06 in reply to: Problem when running SoftRobots python script (SOFA v18.12 on Ubuntu 16.04) #12929Damien MarchalBlockedHello @outtt
I suggest we pursue the investigation about the SparseLDLSolver problem in the corresponding thread: https://www.sofa-framework.org/community/forum/topic/how-to-use-the-component-sparseldlsolver/
Damien.
Damien MarchalBlockedHello,
I compiled sofa master, with metis and SofaSparseSolver plugin and tried the scene.
It worked without problem on my ubuntu.
Can you gives us more details on your setup/OS so we can narrow the investigation ?Damien.
29 January 2019 at 10:15 in reply to: Problem when running SoftRobots python script (SOFA v18.12 on Ubuntu 16.04) #12925Damien MarchalBlockedHi all,
You are totally right, thank you for opening an issue on this topic.
We will discuss the removal of the deprecated component in this PR https://github.com/sofa-framework/sofa/pull/905
The change proposed by Wong is also one option (Wong could you make a PR for that ? Otherwise I will do it).
Feel free to join.
22 January 2019 at 22:17 in reply to: QSqlTable and QSqlDatabase created in QT are not accessible in sofa #12864Damien MarchalBlockedHi rubab,
I have never done these thing myself but I think I understand what you want to do.
There is different options that depend on what you precisely want to do.
Let me explain:
1) If the table view you want to display should be integrated as a widget into the existing runSofa application. Then what you want to do is very similar to what can be found in the “image” plugin. In this plugin there is some sofa component as well as customized UI elements in the “image_gui” directory that show up when clicking on the sofa components.2) If the able view you want to display is in a separated windows and you want it to be displayed in the existing runSofa gui…This should be done in a similar way to the ‘image_gui’ part (the cmake) except that I don’t think there is a way in the existing runSofa gui to display the new window. So this may require some hacking to the runSofa application to had some “extra-menu”.
Hope this helps,
DamienDamien MarchalBlockedHi fatima,
On my side I would do something like saving the file from matlab in the “json” file format and read it from python.
Example of a ‘file.json’ containing some 3d values like that:
{ "values" : [[1.0, 1.0, 1.0], [2.0, 2.0, 2.0], [3.0, 3.0, 3.0]] }
The logic is similar for 1D values or other SurfacePressureConstraint in place of the MechanicalObject.
You can load it in python and using it in Sofa using the standard python loader:
import json def createScene(rootNode): '''Create a sofa scene showing three 'points' with position read from a json file''' data = json.load(open("file.json")) v = rootNode.createObject("MechanicalObject", position=data["values"]) v.showObject = True v.showObjectScale = 10.0
Regards,
DamienDamien MarchalBlockedHi Fayad,
One solution to your problem is to use an animation controller that will update the animation at regular interval using the time of the simulation of the wall clock time depending on what you need.
You can get inspiration from the drafted animation system we implemented in the STLIB:
https://stlib.readthedocs.io/en/latest/_autosummary/splib.animation.htmlHere is a simple example:
# coding: utf-8 # splib is available here: https://github.com/SofaDefrost/STLIB import splib ## This function is called by the animation manager at each timestep, the factor ## is updated to indicate how much has progress the animation. ## The factor is between [0, 1] 0 is the begin of the animation, 1 is the end. def myanimate(target, factor, src, dst): t = [(dst[0]-src[0]) * factor + src[0], (dst[1]-src[1]) * factor + src[1], (dst[2]-src[2]) * factor + src[2]] print("I'm updating the position using: ", factor, " new pos is", t) target.position = t def createScene(rootNode): from splib.animation import animate, AnimationManager ## This will create a single AnimationManager python script controller that will animate all the ## animation on the scene. AnimationManager(rootNode) # The object t = rootNode.createObject("MechanicalObject", position=[0,0,0]) t.showObject=True t.showObjectScale=10 # This fire up an animation, # The movement is computed using the "myanimate" function # The target of the animation is the 't' object # This animation will have 0.5 second duration (simulation time) # 'ping-pong' means that the animation will repeat to-from. animate(myanimate, {"target" : t, "src" : [-1.0,-1.0,0], "dst" : [+1.0, 2.0,0]}, duration=5.0, mode="pingpong" )
Hope this helps.
Regards,
Damien.21 January 2019 at 21:01 in reply to: QSqlTable and QSqlDatabase created in QT are not accessible in sofa #12852Damien MarchalBlockedHi rubab,
I don’t think there is any problem in using QSql with sofa as long as the cmake & dependencies there is not problem with the cmake.
When you say “i copied its headers, cpp, ui,” …can you give more details on where you copied all that, how exactely you are updating cmake and which CMakeLists.txt you are updating.
To help you we probably also need to know if you are doing and in-tree build (so you put your application in the sofa for compilation) or an out-tree one (it means you are doing an external application that you want to use sofa as a library)
Damien.18 January 2019 at 06:42 in reply to: There is an exception error to execute SofaPhysicsAP! Why? #12794Damien MarchalBlockedHi BennyYan,
Same as Hugo, I have never used the SofaPhysicsAPI.
As this seems related to c++ coding maybe opening a bug issue in the
github bugtracker is the way to go as more SOFA developers are consulting it
(compared to the forum)
https://github.com/sofa-framework/sofa/issuesRegards,
DamienDamien MarchalBlockedHi @adamzhang and others,
It is good to hear there is other people interested to use Sofa for robotics.
I’m from the DEFROST research team and there we are working on applying SOFA for soft robotics. You can have more infos of our work at the following address:
In my team we are developing open-source plugins for SOFA geared toward soft-robotics :
– https://github.com/SofaDefrost/ModelOrderReduction
– https://github.com/SofaDefrost/SoftRobotsIn addition to the use of compiled plugin to exchange messages (like the ROS plugin or the CommunicationPlugin one https://github.com/sofa-framework/sofa/pull/534) it is possible to use the python binding of Sofa to to interact to/from sofa with other applications or framework using a messaging protocols. In the SoftRobots plugin there is a minimal example on how to expose sofa data to ROS using the rospy binding. For similar usage we also have used the ZMQ library (http://zeromq.org/) with its python binding.
Of course passing through the python binding has lower performances.Regards,
DamienDamien MarchalBlockedHi @Thassyo,
Did you made any progress on that topic because I have here someone that is starting to work on NN & Sofa and may be interested with what you experienced.
Regards,
DamienDamien MarchalBlockedHi,
You are right this is not working.
But I fear that this binding of simulationStep() method on Node was not designed for such use case.
The easiest solution (not the most elegant one) I can find is to add an updateVisual() method to the node binding to expose the initVisual() that we can found in Simulation.h.
Actually it is very strange that we bind Simulation::animate and not Simulation::initVisual.This will update the visual but this will not trigger the runSofa 3D viewport to update the content of the 3D views but I think this may work if you start runSofa with the -i option (in that case the 3D view is refreshed at regular interval).
But, all that requires to make change on the sofa source code so I suggest to open an issue on github to track this topic: https://github.com/sofa-framework/sofa/issues
Regards,
DamienDamien MarchalBlockedHi,
When the timing are activated with the SOFA_TIMER_ALL some statistic will be visible for python scripts. But all the scripts instance will be aggregated.
To differentiate between instances you need to do that manually using the python binding of the timing API.
There is some basic documentation of the high level API there:
https://www.sofa-framework.org/api/master/plugins/SofaPython/html/md__media_jenkins_sofa-ci-dev_workspace_generate-doxygen_master_sofa_applications_plugins_SofaPython_doc_AdvancedTimer_readMe.htmlBut I personally prefer to use the low level API that directly interact with the timing functions available in the Sofa module.
https://github.com/sofa-framework/sofa/blob/master/applications/plugins/SofaPython/python/SofaPython/PythonAdvancedTimer.pyHope this helps and, in case you think that the documentation is not clear, don’t hesitate to propose improvements we welcome any help.
Regards,
Damien.Damien MarchalBlockedHi rubab,
I’m not sure I get what you exactely want to do.
I have the impression that you are saving some data from sofa into an SQLITE data base and after that you want then to visualize them with a custom user interface based on QTABLEVIEW ?
As you are using a data base to save the data why not implementing the visualization a third party application (with pyQT to make that easy) to avoid all the complexity of coding your QTABLEVIEW’s widget into Sofa (which is possible but sounds much more harder to me).
Regards,
Damien.Damien MarchalBlockedHi all,
I remember to have refactor the loader some time ago. I just quickly looked into it and it definitely should understand xsp 4.0 format and the lspg tag. As this seems related to a possible bug/regression, I opened an issue for this on github.
Damien MarchalBlockedHi Igor,
Despite I have no time to contribute on such topic I found it very interesting. Thanks for the slides.
Regards.
Damien MarchalBlockedHi Thassyo,
It is great to see how deep you already have learned about Sofa.
On my side I rarely use Sofa directly using the c++ interface but I appreciate a lot the SimpleApi to create scenes in c++.
SceneCreator is now deprecated, it is just there of backward compatibility (and it actually implemented on top of the SimpleApi).
The design rational behind the SimpleApi was to make it looking more like the python API. In case you would like to see more function in SimpleApi, don’t hesitate to pass by the github because this is where the software development happens.
https://github.com/sofa-framework/sofaIn case you have specific question on that, feel free to ask.
Regards,
19 December 2018 at 23:37 in reply to: [SOLVED] Could sofa use full Python instead of being embedded in XML file using component #12628Damien MarchalBlockedHi xiaojuan,
I’m not sure I fully understand your question but you can use the classical python debugger pdb for stepping into the python code.
Extract from the doc: https://docs.python.org/2/library/pdb.html
“””
The typical usage to break into the debugger from a running program is to insertimport pdb; pdb.set_trace()
at the location you want to break into the debugger. You can then step through the code following this statement, and continue running without the debugger using the c command.
“””I have never used it but I think it will do what you want.
Damien MarchalBlockedHi Fayad,
We have in the STLIB plugin some class to ease the manipulation of rigid body from python.
The plugin is here:
https://github.com/SofaDefrost/STLIBMore specifically the code to ease the manipulation is at line 103 (the RigidDof class) at
https://github.com/SofaDefrost/STLIB/blob/master/python/splib/numerics/__init__.pyAll this code is drafted and we hope that the next version of the plugin SofaPython3 will solve all that removing the need of these.
There is also similar script in the Compliant plugin (that is already in Sofa). If I remember correctly it is in the python applications/plugins/Compliant/python/StructuralAPI.py
Regards,
EDIT: About the line
‘position = self.mechanical.findData(‘position’).value’
You can alternatively do
‘position= self.mechanical.position’Damien MarchalBlockedHi Maadi,
If your interest is in SoftRobotics, you should try our SoftRobots plugin for Sofa that is available at https://project.inria.fr/softrobot/
Sadely there is no binary version for it, the documentation on how to compile it is
Damien MarchalBlockedHi Fayad,
I tried in a small test to see how I would do a very simplified logic for a cissor.
Basically it is a “cissor” reference frame connected to two “child” frames to hold the local frames for each part of the cissor. The connection between the parent and child is done using a RigidRigidMapping. To any of these frame you can attach visual or collision models.Then I made a python controller which actually connect the keypressed to actual transform of either the reference frame or the two sides when we open/close it.
It is quickly done and I have no idea if it is bullet proof… but here is the result, hoping you will find it useful.
# coding: utf-8 import Sofa def translate(x, t): p = x[0:3] q = x[3:] return [p[0]+t[0], p[1]+t[1], p[2]+t[2]]+q class CissorController(Sofa.PythonScriptController): '''Controller that handle open/close and movement of a cissor''' def __init__(self, node, cissor): self.cissor = cissor def onKeyPressed(self, c): o = None p = None if c == '+': o=0.1 elif c == '-': o=-0.1 elif c=='4': p = 0.1 elif c=='6': p = -0.1 if o is not None: # Open/Close the cissor. q = self.cissor.right.transform.rest_position[0] self.cissor.right.transform.rest_position = translate(q,[o,0.0,0.0]) q = self.cissor.left.transform.rest_position[0] self.cissor.left.transform.rest_position = translate(q,[-o,0.0,0.0]) if p is not None: ## Move along X the cissor q = self.cissor.transform.position[0] self.cissor.transform.position = translate(q,[p,0.0,0.0]) class MyCissor(): '''A Sofa Prefab for a cissor.''' def __init__(self, node, name="MyCissor"): n = node.createChild(name) ## The reference transform to manipulate the whole cissor m = n.createObject("MechanicalObject", template="Rigid3", name="transform") ## The right side of the cissor with its own position/orientation. r = n.createChild("right") r.createObject("MechanicalObject", name="transform", template="Rigid3", position=[1.0,0.5,0.0,0,0,0,1]) r.createObject("RigidRigidMapping", name="map", initialPoints=r.transform.findData("rest_position").getLinkPath()) ## The left side of the cissor with its own position/orientation. l = n.createChild("left") l.createObject("MechanicalObject", name="transform", template="Rigid3", position=[-1.0,0.5,0.0,0,0,0,1]) l.createObject("RigidRigidMapping", name="map", initialPoints=l.transform.findData("rest_position").getLinkPath()) self.node = n def createScene(root): root.createObject("EulerImplicit") root.createObject("CGLinearSolver") c = MyCissor(root).node CissorController(c,c) c.transform.showObject=True c.right.transform.showObject=True c.left.transform.showObject=True
-
AuthorPosts