Home › Forum › SOFA › Using SOFA › [SOLVED] Force feedback not working correctly when using two haptic devices
Tagged: carving, geomagic, Haptic, phantom, SOFA_2006, touch, two haptic devices, Windows_10
- This topic has 3 replies, 3 voices, and was last updated 3 years, 6 months ago by Davacas.
-
AuthorPosts
-
6 May 2021 at 04:23 #19387DavacasBlocked
Hello, everyone.
I currently have a scene with two haptic devices: one device allows me to deform and carve a tetrahedral mesh (using the SofaCarving plugin) and the other device only allows me to deform it, so I can carve with one hand while deforming with the other.
The simulation works fine, but the force feedback on the haptic devices isn’t. My scene is written in XML, and for some reason, both devices get the same feedback as the first device that appears on the code, while the second device doesn’t generate forces on its own. I’m attaching a simplified version of my scene file:
<?xml version="1.0" ?> <Node name="root" showBoundingTree="0" gravity="0 0 0"> <RequiredPlugin name="SofaOpenglVisual"/> <RequiredPlugin name="Geomagic"/> <RequiredPlugin name='SofaHaptics'/> <RequiredPlugin name='SofaSparseSolver'/> <RequiredPlugin name="SofaCarving" /> <VisualStyle displayFlags="" /> <DefaultPipeline verbose="0" depth="6"/> <DefaultContactManager name="response" response="FrictionContact" /> <MinProximityIntersection name="Proximity" alarmDistance="0.10" contactDistance="0.01"/> <GeomagicDriver name="GeomagicDeviceRight" deviceName="Right Device" emitButtonEvent="true" positionBase="1 0 0"/> <GeomagicDriver name="GeomagicDeviceLeft" deviceName="Left Device" emitButtonEvent="true" positionBase="-1 0 0"/> <FreeMotionAnimationLoop/> <LocalMinDistance name="proximity" alarmDistance="0.10" contactDistance="0.01" angleCone="0.1" /> <BruteForceDetection name="detection" /> <LCPConstraintSolver tolerance="0.001" maxIt="1000"/> <CarvingManager active="false" carvingDistance="1.0"/> <Node name="Mesh"> <EulerImplicitSolver name="cg_odesolver" printLog="false" rayleighStiffness="0.1" rayleighMass="0.1" /> <CGLinearSolver name="linear solver" iterations="10" tolerance="1.0e-9" threshold="1.0e-9" /> <MeshGmshLoader name="loader" filename="mesh/liver.msh"/> <MechanicalObject src="@loader" name="Volume" /> <include href="Objects/TetrahedronSetTopology.xml" src="@loader" /> <DiagonalMass massDensity="0.01" /> <TetrahedronFEMForceField name="CFEM" youngModulus="100" poissonRatio="0.45" method="large" /> <FixedConstraint indices="3 39 64" /> <PrecomputedConstraintCorrection recompute="false"/> <Node name="T"> <include href="Objects/TriangleSetTopology.xml" /> <Tetra2TriangleTopologicalMapping name="t2t" input="@../Container" output="@Container" /> <TriangleCollisionModel tags="CarvingSurface"/> <Node name="Visual"> <OglModel name="VisualModel" color="0 0 1 1.0"/> <IdentityMapping input="@../../Volume" output="@VisualModel" /> </Node> </Node> </Node> <Node name="OmniRight"> <MechanicalObject template="Rigid3d" name="DOFs" position="@GeomagicDeviceRight.positionDevice"/> <MechanicalStateController template="Rigid3d" listening="true" mainDirection="-1.0 0.0 0.0" handleEventTriggersUpdate="true"/> </Node> <Node name="InstrumentRight" > <EulerImplicitSolver name="ODE solver" rayleighStiffness="0.01" rayleighMass="0.01" /> <SparseLDLSolver /> <MechanicalObject name="instrumentState" template="Rigid3" /> <UniformMass name="mass" totalMass="1.0" /> <RestShapeSpringsForceField stiffness='1000000' angularStiffness='1000000' external_rest_shape='@../OmniRight/DOFs' points='0' external_points='0'/> <LCPForceFeedback activate="true" forceCoef="1.0"/> <LinearSolverConstraintCorrection /> <Node name="VisuTool" > <MeshObjLoader name="meshLoader_1" filename="Demos/Dentistry/data/mesh/dental_instrument_centerline.obj" handleSeams="1" translation="-0.5 0 0"/> <OglModel name="InstrumentVisualModel" src="@meshLoader_1" color="1 1 1 1.0" ry="-180" dz="3.5" dx="-0.3"/> <RigidMapping name="MM->VM mapping" input="@instrumentState" output="@InstrumentVisualModel"/> </Node> <Node name="CollisionModel" > <MeshObjLoader filename="Demos/Dentistry/data/mesh/dental_instrument_centerline.obj" name="loader" translation="-0.5 0 0"/> <MeshTopology src="@loader" name="InstrumentCollisionModel" /> <MechanicalObject src="@loader" name="instrumentCollisionState" ry="-180" dz="3.5" dx="-0.3" /> <PointCollisionModel contactStiffness="100" tags="CarvingTool"/> <TriangleCollisionModel /> <RigidMapping name="MM->CM mapping" input="@instrumentState" output="@instrumentCollisionState" /> </Node> </Node> <Node name="OmniLeft"> <MechanicalObject template="Rigid3d" name="DOFs" position="@GeomagicDeviceLeft.positionDevice"/> <MechanicalStateController template="Rigid3d" listening="true" mainDirection="-1.0 0.0 0.0" handleEventTriggersUpdate="true"/> </Node> <Node name="InstrumentLeft" > <EulerImplicitSolver name="ODE solver" rayleighStiffness="0.01" rayleighMass="0.01" /> <SparseLDLSolver /> <MechanicalObject name="instrumentState" template="Rigid3" /> <UniformMass name="mass" totalMass="1.0" /> <RestShapeSpringsForceField stiffness='1000000' angularStiffness='1000000' external_rest_shape='@../OmniLeft/DOFs' points='0' external_points='0'/> <LCPForceFeedback activate="true" forceCoef="1.0"/> <LinearSolverConstraintCorrection /> <Node name="VisuTool" > <MeshObjLoader name="meshLoader_1" filename="Demos/Dentistry/data/mesh/dental_instrument_centerline.obj" handleSeams="1" translation="0.5 0 0"/> <OglModel name="InstrumentVisualModel" src="@meshLoader_1" color="1 1 1 1.0" ry="-180" dz="3.5" dx="-0.3"/> <RigidMapping name="MM->VM mapping" input="@instrumentState" output="@InstrumentVisualModel" /> </Node> <Node name="CollisionModel" > <MeshObjLoader filename="Demos/Dentistry/data/mesh/dental_instrument_centerline.obj" name="loader" translation="0.5 0 0"/> <MeshTopology src="@loader" name="InstrumentCollisionModel" /> <MechanicalObject src="@loader" name="instrumentCollisionState" ry="-180" dz="3.5" dx="-0.3" /> <PointCollisionModel contactStiffness="100"/> <TriangleCollisionModel /> <RigidMapping name="MM->CM mapping" input="@instrumentState" output="@instrumentCollisionState" /> </Node> </Node> </Node>
In this example, both devices output the force sent to the right device, since it is the first that appears in the file. The left device doesn’t generate any forces by itself; it only sends feedback when the right device does. In this example, if I put the left device first, then both devices output the feedback sent to that device.
I’m working with two 3D Systems’ Touch haptic devices, running SOFA 20.06 on a 64 bit Windows 10 with the Geomagic and SofaCarving plugins.
Any help would be very appreciated.
Have a nice day!
7 May 2021 at 23:20 #19405HugoKeymaster8 May 2021 at 11:42 #19413epernodBlockedHi @davacas,
yes this is logical that you get the same force feedback in both tools because if you don’t specify which LCPForceFeedback to look for in your GeomagicDriver, it will take the first one found while parsing your scene.
To avoid that you have to specify in each GeomagicDriver:<GeomagicDriver name="GeomagicDeviceRight" deviceName="Right Device" emitButtonEvent="true" positionBase="1 0 0" forceFeedBack="@InstrumentRight/LCPFF_Right"/> <GeomagicDriver name="GeomagicDeviceLeft" deviceName="Left Device" emitButtonEvent="true" positionBase="-1 0 0" forceFeedBack="@InstrumentLeft/LCPFF1_Left"/>
And don’t forget to set the name of the LCPForceFeedback
Best regards,
14 May 2021 at 02:45 #19440DavacasBlockedHi, @epernod. Thank you for your fast and concise answer!
Wow, I can’t believe it was this simple! I had deleted that link because I didn’t need it back when I was testing with just one device, but by the time I integrated the second device, I had completely forgotten about it.
Thank you, @Hugo and @epernod for taking the time to answer me. I’m marking the post as solved now.
Have a great day!
-
AuthorPosts
- You must be logged in to reply to this topic.