SEARCH
TOOLBOX
LANGUAGES
Sensable Howto

Sensable Howto

From SOFAWiki

Jump to: navigation, search

Contents

How to use SensAble device in SOFA

Requirements

The SensablePlugin requires both OpenHaptics SDK and Phantom drivers to be installed on your system. The current OpenHapticsSDK ( 3.0 ) academic edition already provides the Phantom Device Drivers so you should only have to download this package. Latest drivers from SensAble are compatible for Microsoft Windows and GNU/Linux, both in 32 and 64 bits.

Configuration and Compilation

We need to configure to activate SensAble support in SOFA. In order to do that, edit the configuration file (or use the utility SofaConfiguration) and uncomment (or enable) the option :

	SOFA_HAVE_SENSABLE

and update Makefiles, executing

	./Project Linux.sh

on Linux systems or

	Project VC7.bat (Visual Studio 2003)
	Project VC8.bat (Visual Studio 2005)
	Project VC9.bat (Visual Studio 2008)

on Windows systems.

and of course, compile using make or Visual Studio.

Use

NB : This Tutorial will only describes how to use NewOmniDriver component ; OmniDriver & SensAble application are completely obsolete ( i.e segfault, freeze, malfunction, etc)

Omni Manipulation

First, don't forget to load the newly created plugin libSensablePlugin.so/dylib/dll (depending of your OS). After that, just put an object called NewOmniDriver in your scene file (preferably in the root node)

	<NewOmniDriver  />

Customizable parameters are :

- omniVisu : draw a virtual representation of your Omni device in the scene world to quickly transform coordinates (see following parameters). Very usesul for debugging
- positionBase (Vec3), orientationBase (Quaternion) and scale (float) : transformations to apply on coordinates given by your device (haptic frame -> world frame)
- forceScale (float) : force scale applied to the force feedback.
- permanent : apply permanently force in your scene. Otherwise, you have to push one button to activate force feedbacks.

positionTool (Vec3) and orientationTool (Quaternion) are the position and orientation of the tool in the omni end effector frame. (should not be changed)

Interaction with the scene

The next step is to use the recently fetched position and orientation. The main use is to map this DOF (degree of freedom) with an object in the scene, that is to say a MechanicalState. This method is done through a

	<MechanicalStateController  />

which modifies the Mechanical State located in the same node(NewOmniDriver sends events which are automatically read by the MechanicalState) After that, use this mechanical state (which contains only one DOF) with mappings to move objects, etc.

Force Feeback

At last, we have to send forces to the haptic device to give scene->user interactions. There are different ways to do this. One method is to use

	<LCPForceFeedback />

Place this object in the same node as the mechanical state which will be exposed to forces (forcefield, collision, etc). (Remember that you have to push the button on the device to get forces, unless you have activated the "permanent" flag in NewOmniDriver)

Example

You can find a working example of the NewOmniDriver component in /examples/Demos/Dentistry/dentalSurgeryLCPNewOmni.scn where a NewOmniDriver is used ; and a Forceback is applied as well. This is the xml of the scene

<!-- 
Using LCP contact detection and resolution:
 + Added a driver for the Omni phantom device 
 + Added a mechanical state controller that gathers data from the phantom and updates the position of a representation of the device in the simulation 
 + Added a computation (LCPForceFeedback) of the haptic forces 
 + Added VectorSpringForceField && JointSpringForceField to link the mouvements of the Omni phantom and the instrument
-->
 
<Node name="root" dt="0.005" showBehaviorModels="0" showCollisionModels="0" showMappings="0" showForceFields="0" >
	<Gravity name="G" gravity="0 -9.8 0" />
	<CollisionPipeline name="pipeline" depth="6" verbose="0"/>
	<BruteForceDetection name="detection" />
	<CollisionResponse name="response" response="FrictionContact" />
	<LocalMinDistance name="proximity" alarmDistance="0.3" contactDistance="0.15" angleCone="0.0" />
	<MasterContactSolver />
	<NewOmniDriver scale="10.0" positionBase="0 1 -0.5" omniVisu="false" />
 
	<Node name="Tooth" >
		<Node name="VisualModel" >
			<OglModel name="ToothVisualModel" fileMesh="data/mesh/tooth-closed.obj" color="white" /> 
		</Node>
		<Node name="CollisionModel" >
		 	<MeshLoader filename="data/mesh/tooth-closed.obj" />
			<Mesh name="ToothCollisionModel" />
			<MechanicalObject name="toothState" />		
			<Triangle name="tooth" contactStiffness="100" simulated="0" moving="0"/>
			<Line name="tooth" contactStiffness="100" simulated="0" moving="0"/>	
			<Point name="tooth" contactStiffness="100" simulated="0" moving="0"/>	
		</Node>
	</Node>
 
	<!-- ADDED: the Mechanical state Controller gathers events from the Omni driver and populates the Mechanical state -->
	<Node name="Omni">
		<MechanicalObject template="Rigid" name="DOFs" position="1.2 1.6 -3.55  0 0 0 1"/>
		<MechanicalStateController template="Rigid" listening="true" mainDirection="-1.0 0.0 0.0" handleEventTriggersUpdate="true"/>
		<Node name="RefModel">
			<MeshLoader filename="data/mesh/dental_instrument_centerline.obj" />
			<Mesh />
			<MechanicalObject name="instrumentCollisionState" rx="180" rz="150" dx="-1.2" dy="-1.6" dz="3.55"/>
			<RigidMapping />
		</Node>
	</Node>
 
	<Node name="Instrument" >
		<EulerImplicitSolver name="ODE solver" rayleighStiffness="0.01" rayleighMass="1.0" />
		<CGLinearSolver name="linear solver" iterations="25" tolerance="1e-10" threshold="10e-10" /> 
		<MechanicalObject name="instrumentState" template="Rigid" position="1.2 1.6 -3.55  0 0 0 1"/>
		<UniformMass name="mass" totalmass="0.05" filename="BehaviorModels/dental_instrument.rigid" />
		<LCPForceFeedback activate="true" forceCoef="0.005"/> <!-- ADDED : Compute a force-feedback for the device -->
		<UncoupledConstraintCorrection/>
		<Node name="VisualModel" >
			<OglModel name="InstrumentVisualModel" fileMesh="data/mesh/dental_instrument.obj" color="1.0 0.2 0.2 1.0" rx="180" rz="150" dx="-1.2" dy="-1.6" dz="3.55"/>
			<RigidMapping name="MM->VM mapping" object1="instrumentState" object2="InstrumentVisualModel" />
		</Node>
		<Node name="CollisionModel" >
			<MeshLoader filename="data/mesh/dental_instrument_centerline.obj" />
			<Mesh name="InstrumentCollisionModel" />
			<MechanicalObject name="instrumentCollisionState" rx="180" rz="150" dx="-1.2" dy="-1.6" dz="3.55"/>
			<Triangle name="instrument" contactStiffness="10" />
			<Line name="instrument" contactStiffness="10" />
			<Point name="instrument" contactStiffness="10" /> 
			<RigidMapping name="MM->CM mapping" object1="instrumentState" object2="instrumentCollisionState" />
		</Node>
		<VectorSpringForceField  object1="Omni/RefModel/instrumentCollisionState" object2="Instrument/CollisionModel/instrumentCollisionState" stiffness="10" viscosity="0" />
		<JointSpringForceField template="Rigid" name="joint springs" object1="Omni" object2="instrumentState" 
			spring="BEGIN_SPRING 0 0 KS_T 50 50  KS_R 500.0 500.0  KS_B 500.0  KD 0.0 END_SPRING"  />
	</Node>
</Node>

Image:omni_visu_normal.jpg Image:omni_visu_interactions.jpg