Geomagic
Installing the OpenHaptics SDK
The Geomagic drivers and SDK can be directly downloaded from the 3DSystem website:
Following the above-mentioned links, you should find a programmers guide for assistance. The installation directory should be:
C:/OpenHaptics
for Windows/opt/OpenHaptics/Developer/3.4-0/
for Linux
You can check the install by running the Geomagic_Touch_Setup and Geomagic_Touch_Diagnostic applications (located in /opt/geomagic_touch_device_driver/
for Linux). To do so, your Geomagic device must now be connected. If you are using Ethernet connection, make sure the address assignment of the wired connection is set to "Link-Local Only" instead of "Automatic".
NB : for Linux, after the installation, if you already had a version of Qt installed, you might face a conflict with Qt versions. This is due to a script named geomagic.sh created at the Geomagic installation (in /etc/profile.d/). To fix this, you can remove or comment the two following lines in the geomagic.sh file:
export LD_LIBRARY_PATH=/opt/geomagic_touch_device_driver/lib
export QT_PLUGIN_PATH=/opt/geomagic_touch_device_driver/lib/plugins
Compilation in SOFA
Now in SOFA:
- activate the plugin in cmake-gui by setting the flag
PLUGIN_GEOMAGIC
to true. NB: Make sure to have closed CMake after the installation of the OpenHaptics library, described above. - compile SOFA, which should trigger the compilation of the Geomagic plugin
- enjoy the power of the Geomagic haptic interfaces with SOFA and give a try to the example scene (examples/DemoGeomagic.scn)
And let us know about your Geomagic simulations!
Using the plugin in a simulation
Load the plugin
Like any other plugin in SOFA, you need to load it dynamically in your scene if you want to use classes defined in this plugin. For the Geomagic plugin, to benefit from the GeomagicDriver, you need to add in your root node:
Add the GeomagicDriver
To interface the Geomagic device with the simulation, all you need is to add the GeomagicDriver class into your scene:
<GeomagicDriver name="GeomagicDevice" deviceName="Default Device" scale="1" drawDeviceFrame="1" positionBase="0 0 0" orientationBase="0 0 0 1"/>
This class will recover the motion of the device and allow for communication with the simulation.
Control an object in the scene
The use of the GeomagicDriver in a scene could be to control a rigid object in a simulation. For install, let's control one rigid point with
<GeomagicDriver name="GeomagicDevice" deviceName="Default Device" scale="1" drawDeviceFrame="1" positionBase="0 0 0" orientationBase="0 0 0 1"/>
<MechanicalObject template="Rigid" name="GeomagicMO" position="@GeomagicDevice.positionDevice" />
Then, as in any SOFA simulation, you can map this rigid point to any other object (visual, mechanical or collision model).
Get haptic feedback
Now, if you want to control an object and get haptic feedback due to collision, the scene becomes more complicated. You will need to set up the entire collision pipeline in order to solve the Linear Complementary Problem (LCP), thus finding its solutions: the Lagrange multipliers.
In the root node, the collision pipeline needs to be defined with:
<RequiredPlugin name="Geomagic plugin" pluginName="Geomagic" />
<FreeMotionAnimationLoop/>
<CollisionPipeline name="pipeline" depth="6" verbose="0"/>
<BruteForceBroadPhase/>
<BVHNarrowPhase/>
<LocalMinDistance name="proximity" />
<CollisionResponse name="response" response="FrictionContactConstraint" />
<LCPConstraintSolver tolerance="0.001" maxIt="1000"/>
<GeomagicDriver name="GeomagicDevice" deviceName="Default Device" scale="1" drawDeviceFrame="1" positionBase="0 0 0" orientationBase="0 0 0 1" />
In the node describing your object on which you want to recover the force feedback, you need to add a LCPForceFeedback. This class computes the force applied on the object based on the constraint problem. During the simulation, the GeomagicDriver will look for a pointer to a LCPForceFeedback to get the force value to return to the haptic interface. The node therefore can be written:
<Node name="Instrument-1" >
<EulerImplicitSolver name="ODE solver" rayleighStiffness="0.05" rayleighMass="1.0" />
<CGLinearSolver name="linear solver" iterations="25" tolerance="1e-10" threshold="10e-10" />
<MechanicalObject name="instrumentState" position="@PATH_TO_GEOMAGICDRIVER/GeomagicDevice.positionDevice" template="Rigid3d" />
<UniformMass name="mass" totalMass="0.005" />
<LCPForceFeedback activate="true" forceCoef="0.005"/> <!-- this class computes the force to return back -->
<UncoupledConstraintCorrection/>
<!-- This node is the collision model associated to our controlled object -->
<Node name="CollisionModel" >
<MeshOBJLoader filename="MY_COLLISION_SURFACE_MODEL.obj" name="loader"/>
<Mesh src="@loader" name="InstrumentCollisionModel" />
<MechanicalObject src="@loader" name="instrumentCollisionState" />
<LineCollisionModel name="instrument" />
<PointCollisionModel name="instrument" />
<RigidMapping name="CollisionMapping" input="@instrumentState" output="@instrumentCollisionState" />
</Node>
</Node>