Home › Forum › SOFA › Using SOFA › [SOLVED] Collision Callback function in python
Tagged: 64_bits, collision, Linux_ubuntu, Plugin_SoftRobots, SOFA_1906
- This topic has 20 replies, 6 voices, and was last updated 3 years, 4 months ago by Scheikl.
-
AuthorPosts
-
27 July 2020 at 21:50 #16967billBlocked
Hello,
I would like to execute a piece of code when a collision is detected, using SofaPython. From what I can tell from the API, I would want to call getCollisionPipeline() on the rootNode and then I should be able to poll getResponseList() to find out if a collision has occurred (or something along those lines).
However, to my knowledge, this can’t be done using SofaPython because the getCollisionPipeline() api call is not implemented. Is there another way to do this?
Thank you
10 August 2020 at 16:24 #17015fedevBlockedInterested as well
14 September 2020 at 23:13 #17137HugoKeymasterInteresting point.
Two possible solutions, but at my best knowledge none have been yet implemented:
– creating a dedicated Event captured by Python when a contact really occurs (saved after the Narrow phase)
– calling a specific C++ function when a contact really occurs and binding this function in Python
@bmarques does such a question ring a bell?Hugo
9 December 2020 at 14:42 #17988tschueliaBlocked19 December 2020 at 00:25 #18061HugoKeymasterHey @bill757 @fedev @tschuelia
I do not think a function can be directly called from Python. This I will need to check.
However, you could add a ContactListener in your simulation and at each time step using your python script read into the collision information stored in this listener.
I could create a dedicated example in the SofaPython3 plugin in the first week of 2021.
Best,
Hugo
22 January 2021 at 09:40 #18375tschueliaBlockedHi Hugo, sorry for the very late response.
Using a ContactListener works perfectly, thank you 🙂28 April 2021 at 05:07 #19329bttBlockedDear @hugo, @tschuelia
I tried to add ContactListener to my scene but It seems unproperly constructed. Could you please share the line of code to add this component?
I use sofapython to build up simulation model. Thank you for any help
Best28 April 2021 at 09:03 #19330ScheiklBlockedHi @newbie,
please note, that there is a difference between SofaPython and the Plugin SofaPython3.If you are using SofaPython3, you can add a ContactListener with
listener = scene_node.addObject( "ContactListener", name="TestContactListener", collisionModel1=body1.collision.PointCollisionModel.getLinkPath(), collisionModel2=body2.collision.TriangleCollisionModel.getLinkPath(), )
This one will listen for contacts between PointCollisionModels on body1 and TriangleCollisionModels on body2.
Cheers,
Paul28 April 2021 at 17:41 #19341bttBlockedThank you @scheikl, my simulation is built up using python2. So, it would be more convenient for me if your code can be converted to python2. I tried with this line but not success:
contactlistener.createObject('ContactListener', collisionModel1 = '@SkinCollision.LineCollisionModel', collisionModel2 = '@collisionFinger.LineCollisionModel')
28 April 2021 at 18:23 #19342ScheiklBlockedHi @newbie,
sadly I started using Sofa with SofaPython3 directly so I’ve never really used SofaPython2.Is there an error message you could post?
Is the relative path to
SkinCollision
andcollisionFinger
correct?Cheers,
Paul14 May 2021 at 07:47 #19441bttBlockedThank you @scheikl for following up my problem, the general structure of my scene is shown below:
def createScene(rootNode): ... # Finger node finger = rootNode.createChild('finger') #collision collisionFinger = finger.createChild('collisionFinger') collisionFinger.createObject('MeshTopology', src='@loader', name='topo') collisionFinger.createObject('MechanicalObject', name='collisMech') collisionFinger.createObject('TriangleCollisionModel', name = 'triangle', selfCollision=0) collisionFinger.createObject('LineCollisionModel', name = 'line', selfCollision=False) collisionFinger.createObject('PointCollisionModel', name = 'point', selfCollision=False) # Skin node skin = rootNode.createChild('skin') # Collision skinCollision = skin.createChild('SkinCollision') skinCollision.createObject('MeshTopology', src='@loader', name='topology') skinCollision.createObject('MechanicalObject', name='collisMech') skinCollision.createObject('TriangleCollisionModel', name = 'triangle', selfCollision=0) skinCollision.createObject('LineCollisionModel', name = 'line', selfCollision=0) skinCollision.createObject('PointCollisionModel', name = 'point', selfCollision=0) # Contact listener contactlistener = rootNode.createChild('contactlistener') contactlistener.createObject('ContactListener', collisionModel1 = '@skin.SkinCollision', collisionModel2 = '@finger.collisionFinger')
However, an error message popped up when I loaded this scene:
[ERROR] [DAGNode(contactlistener)] Parsing Link "@skin.SkinCollision": a Data field name is specified while an object was expected. [ERROR] [DAGNode(contactlistener)] Parsing Link "@finger.collisionFinger": a Data field name is specified while an object was expected. [ERROR] [PythonScript] RuntimeError: Unable to create 'ContactListener' of type 'ContactListener' in node 'contactlistener'. Object type ContactListener<> was not created The object is in the factory but cannot be created. Requested template : None Used template : None Reason(s) : Data attributes 'collisionModel1' and 'collisionModel2' are not pointing to valid collision models.
It seems I did not set the paths for two propoerties ‘collisionModel1’ and ‘collisionModel2’. Could you (or any other suggestion will be appreciated) please point out what I did wrong? Thank you very much
Best regards,
btt14 May 2021 at 09:16 #19444ScheiklBlockedHi @newbie,
by specifyingcollisionModel1 = '@skin.SkinCollision'
you are not pointing to an actual collision model, but to a SofaNode that contains multiple collision models.Try changing that to
contactlistener.createObject('ContactListener', collisionModel1 = '@skin.SkinCollision.TriangleCollisionModel', collisionModel2 = '@finger.collisionFinger.PointCollisionModel')
The object should now listen for collisions between the
TriangleCollisionModel
of the skin and thePointCollisionModel
of finger.Cheers,
Paul14 May 2021 at 10:28 #19445bttBlockedHi @Scheikl, I did follow your construction but the same error has appeared. Hope you have another idea. Anyway, I appreciate your kind support.
Best regards,
Nhan14 May 2021 at 12:32 #19446ScheiklBlockedHi @newbie,
ah theContactListener
is not in the root node, so your path misses going up one step in the tree.
You could trycontactlistener.createObject('ContactListener', collisionModel1 = '@../skin.SkinCollision.TriangleCollisionModel', collisionModel2 = '@../finger.collisionFinger.PointCollisionModel')
Cheers,
Paul14 May 2021 at 14:59 #1944714 May 2021 at 15:10 #19448ScheiklBlockedHi @newbie,
I totally missed the fact, that you gave the models a specific name, sorry. 😀
Try replacing the type of Object (TriangleCollisionModel) with the name you gave it (triangle). Same for the PointCollisionModel.Cheers,
Paul14 May 2021 at 15:14 #19449bttBlockedHi @Scheikl, in fact, I did it already but nothing changed :). I tried to play around with this component for the last couple of days but it is still not successful :D.
14 May 2021 at 18:44 #19452ScheiklBlockedHi @newbie,
I just tested the scene, and the following works fine for me:contactlistener.addObject( "ContactListener", collisionModel1="@/finger/collisionFinger/triangle", collisionModel2="@/skin/SkinCollision/point", )
Cheers,
Paul15 May 2021 at 15:36 #19456bttBlockedHi @Scheikl, it is successfully added in SOFA scene. Now I am curious how to extract contact information by using python. I open up the property table of this component and see nothing (it seems wrong). Thank you for your patient.
best
btt16 May 2021 at 17:18 #19458ScheiklBlockedHi @newbie,
you might want to check out SofaPython3.There is a binding for the ContactListener, so you can create a ContactListener object with
listener = contactlistener.addObject( “ContactListener”, collisionModel1=”@/finger/collisionFinger/triangle”, collisionModel2=”@/skin/SkinCollision/point”, )
Now you can add any functions from the c++ code to create bindings for it.
Sadly I really do not know how to do that with SofaPython2.
Cheers,
Paul16 August 2021 at 09:48 #19457ScheiklBlockedHi @newbie,
you might want to check out SofaPython3.There is a binding for the ContactListener, so you can create a ContactListener object with
`
listener = contactlistener.addObject(
“ContactListener”,
collisionModel1=”@/finger/collisionFinger/triangle”,
collisionModel2=”@/skin/SkinCollision/point”,
)
`
Now you can add any functions from the c++ code to create bindings for it.
Sadly I really do not know how to do that with SofaPython2.
Cheers,
Paul -
AuthorPosts
- You must be logged in to reply to this topic.