outline - stanford ai labai.stanford.edu/~csewell/research/lecturechai.pdf• typical structure of a...

7
1 Outline What is CHAI? Descriptions of each of the CHAI libraries and classes Typical structure of a CHAI program Special notes about CHAI Choosing a compiler and using it to create a GUI and a haptically-enabled virtual environment Code for a simple example program Special notes about using the haptic devices What is CHAI? Computer Haptics and Active Interfaces A freely-available API that will enable you to quickly write your first haptically-enabled virtual environment A useful platform used by many research labs working on haptics for various purposes By Francois Conti, Federico Barbagli, Dan Morris, Chris Sewell CHAI Features Open source C++ and OpenGL based Supports most commercially available desktop devices SensAble (Phantom 1.0, Phantom 1.5, Desktop, Omni) Force Dimension (Delta, Omega) MPB Freedom 6S Support for I/O boards to allow you to build custom devices Servotogo, Sensoray626 Support for various compilers Built-in algorithms (god-object, friction, collision detection) Mesh loaders (.3ds and .obj); texture loaders (.bmp) Can be used as a Low-level API to talk to devices High-level API with visual and haptic rendering support Included examples include dynamics (linked with the Open Dynamics Engine library), a haptics ActiveX control, object loader, rotational friction (record player demo), mass-spring dynamics, and more The CHAI Libraries Scenegraph Displays Graphics Devices Tools Forces Collisions Files Math Timers Widgets The CHAI Libraries : Scenegraph Scenegraph cWorld : a container for all the objects of a virtual environment (VE) cCamera : defines a viewpoint for looking at the VE cLight : defines a light for illuminating the VE cGenericObject : base class for objects with which you interact in the VE cMesh : a collection of triangles; can be loaded from a file using Files library; graphically rendered; contains a collision detector from Collisions library that can be used with algorithms in Forces library to compute haptic forces cGenericPotentialField : base class for more general-purpose objects; requires derived classes to calculate a force based on device position and render itself cShapeSphere : renders a sphere graphically (gluSphere) and haptically (potential field) cShapeTorus : renders a torus graphically (glutSolidTorus) and haptically (potential field) Displays Graphics Devices Tools Forces Collisions Files Math Timers Widgets

Upload: tranthien

Post on 24-Mar-2018

220 views

Category:

Documents


2 download

TRANSCRIPT

1

�������������� ������

�������������������������

Outline• What is CHAI?• Descriptions of each of the CHAI libraries

and classes• Typical structure of a CHAI program• Special notes about CHAI• Choosing a compiler and using it to create a

GUI and a haptically-enabled virtual environment

• Code for a simple example program• Special notes about using the haptic devices

What is CHAI?• Computer Haptics and Active Interfaces• A freely-available API that will enable you to quickly write your

first haptically-enabled virtual environment • A useful platform used by many research labs working on

haptics for various purposes• By Francois Conti, Federico Barbagli, Dan Morris, Chris Sewell

CHAI Features• Open source• C++ and OpenGL based• Supports most commercially available desktop devices

– SensAble (Phantom 1.0, Phantom 1.5, Desktop, Omni)– Force Dimension (Delta, Omega)– MPB Freedom 6S

• Support for I/O boards to allow you to build custom devices– Servotogo, Sensoray626

• Support for various compilers• Built-in algorithms (god-object, friction, collision detection)• Mesh loaders (.3ds and .obj); texture loaders (.bmp)• Can be used as a

– Low-level API to talk to devices– High-level API with visual and haptic rendering support

• Included examples include dynamics (linked with the Open Dynamics Engine library), a haptics ActiveX control, object loader, rotational friction (record player demo), mass-spring dynamics, and more

The CHAI Libraries• Scenegraph• Displays• Graphics• Devices• Tools• Forces• Collisions• Files• Math• Timers• Widgets

The CHAI Libraries : Scenegraph• Scenegraph

– cWorld : a container for all the objects of a virtual environment (VE)– cCamera : defines a viewpoint for looking at the VE– cLight : defines a light for illuminating the VE– cGenericObject : base class for objects with which you interact in the VE

• cMesh : a collection of triangles; can be loaded from a file using Files library; graphically rendered; contains a collision detector from Collisions library that can be used with algorithms in Forces library to compute haptic forces

• cGenericPotentialField : base class for more general-purpose objects; requires derived classes to calculate a force based on device position and render itself

– cShapeSphere : renders a sphere graphically (gluSphere) and haptically (potential field)– cShapeTorus : renders a torus graphically (glutSolidTorus) and haptically (potential field)

• Displays• Graphics• Devices• Tools• Forces• Collisions• Files• Math• Timers• Widgets

2

The CHAI Libraries : Displays• Scenegraph• Displays

– cViewport : defines a context on GUI for OpenGL to draw onto• Graphics• Devices• Tools• Forces• Collisions• Files• Math• Timers• Widgets

The CHAI Libraries : Graphics• Scenegraph• Displays• Graphics

– cTriangle : primitive type used by meshes in Scenegraph library– cVertex : primitive type for vertices of a triangulated mesh– cMaterial : defines graphic (e.g. color) and haptic (e.g. stiffness)

properties for an object (such as a mesh)– cTexture2D : defines a bitmap texture for graphic rendering of a mesh– cShaders : vertex and fragment shaders for advanced graphic rendering

• Devices• Tools• Forces• Collisions• Files• Math• Timers• Widgets

The CHAI Libraries : Devices• Scenegraph• Displays• Graphics• Devices

– cGenericDevice : base class for all hardware interfaces; requires derived classes to implement open(), close(), initialize(), and command(), which can be used to get/set forces/positions, depending on device

• cVirtualDevice : software interface that allows you to move the haptic interface point around in a VE with a mouse; forces are drawn with vectors

• cPhantomDevices• cDeltaDevices• cFreedom6SDevice• cDriverSensoray626• cDriverServotogo

• Tools• Forces• Collisions• Files• Math• Timers• Widgets

The CHAI Libraries : Tools• Scenegraph• Displays• Graphics• Devices• Tools

– cGenericTool : base class for tools in a VE; requires derived classes to implementupdatePose(), computeForces(), applyForces()

• cGeneric3dofPointer : contains a pointer to a device interface (from Devices library); calculates 3dof forces by summing contributions from a list of cGenericPointForceAlgoobjects (from Forces library); by default contains one cProxyPointForceAlgo object and one cPotentialFieldForceAlgo object

– cPhantom3dofPointer : sets up pointer to a Phantom device interface– cDelta3dofPointer : sets up pointer to a Delta/Omega device interface– cFreedom6S3dofPointer : sets up pointer to a Freedom 6S device interface– cMeta3dofPointer : automatically determines available hardware device and sets up pointer

• Forces• Collisions• Files• Math• Timers• Widgets

The CHAI Libraries : Forces• Scenegraph• Displays• Graphics• Devices• Tools• Forces

– cGenericPointForceAlgo : base class for algorithms that compute forces based on a 3dof point interaction; requires derived classes to implement computeForces()

• cProxyPointForceAlgo : computes forces using proxy algorithm; calls world to check for collisions, which descends through all its children and calls collision detection method (from Collisions library) for all that have a CD object

• cPotentialFieldForceAlgo : loops through all children of the world and calls computeForces() for all that are of a type derived from cGenericPotentialField (from Scenegraph library) and adds up all contributions

• Collisions• Files• Math• Timers• Widgets

The CHAI Libraries : Collisions• Scenegraph• Displays• Graphics• Devices• Tools• Forces• Collisions

– cGenericCollision : base class for algorithms that test for intersection between a line segment and a triangulated mesh; requires derived classes to implement computeCollision() given two endpoints of line segment; contain lists of cTriangles (from Graphics library) populated from a cMesh object (from Scenegraph library)

• cCollisionBrute : loops through all triangles in list, calling cTriangle’s computeCollision() method with line segment

• cCollisionAABB : builds an axis-aligned bounding-box hierarchy to speed up collision detection; calls cTriangle’s computeCollision() method at leaf nodes

• cCollisionSpheres : builds a sphere tree hierarchy to speed up collision detection; calls cTriangle’s computeCollision() method at leaf nodes

• Files• Math• Timers• Widgets

3

The CHAI Libraries : Files• Scenegraph• Displays• Graphics• Devices• Tools• Forces• Collisions• Files (mesh loaders are functions, not classes)

– cLoadMeshFromFile : decides to load .3ds or .obj file based on file extension; uses either cLoadFileOBJ or cLoadFile3DS

– cLoadFileOBJ : builds a cMesh object (from Scenegraph library), or a tree of cMeshes and cMaterials (from Graphics library), from .obj file

– cLoadFile3DS : builds a cMesh object (from Scenegraph library), or a tree of cMeshes and cMaterials (from Graphics library), from .3ds file

– cImageLoader : decides to load .bmp or .tga file based on file extension; uses either cFileLoaderBMP or cFileLoaderTGA object; stores image after loading

– cFileLoaderBMP : reads in a bitmap (usually used for applying a texture)– cFileLoaderTGA : reads in a tga file (usually used for applying a texture)

• Math• Timers• Widgets

The CHAI Libraries : Math• Scenegraph• Displays• Graphics• Devices• Tools• Forces• Collisions• Files• Math

– Defines cVector3d, cMatrix3d, and many functions on them, such as result = cMul(matrix1, matrix2), vector1.addr(vector2, result); used throughout CHAI as primitive data structures

– Also defines a cStr class for strings and functions for conversions from other data types

• Timers• Widgets

The CHAI Libraries : Timers• Scenegraph• Displays• Graphics• Devices• Tools• Forces• Collisions• Files• Math• Timers

– cPrecisionClock : used for high precision time measurements (e.g., for performance assessment)

– cPrecisionTimer : manages high-rate callbacks, such as for haptic loop

• Widgets

The CHAI Libraries : Widgets• Scenegraph• Displays• Graphics• Devices• Tools• Forces• Collisions• Files• Math• Timers• Widgets

– cFont : for writing text in a VE– cPanel : for creating 2D rectangles in a VE– cLabelPanel : for creating 2D rectangles with text (such as buttons) in a VE– cBitmap : for displaying a 2D bitmap in a VE

The Typical Structure of a CHAI Program• Header file

– #include’s– Variable declarations

• Initialization (often in constructor of the main GUI form)– Create a world, camera, light, and viewport (linked to a window handle from the GUI)– Create objects, specify their material properties, and add them to the world

• Explicitly define the triangles of a cMesh• Load a mesh from a .obj or .3ds file• Derive a subclass of cGenericPotentialField, and create objects of this type

– Initialize timers for graphic and haptic callbacks• Haptics initialization (often in a button click callback)

– Create a tool and add it to the world– Set tool workspace, align coordinate frames, compute global positions– Start tool, set forces on, set callback function for haptic timer

• Graphics callback (~30 Hz)– Render the viewport

• Haptics callback (~1000 Hz)– Read device position (and possibly orientation)– Compute forces– Apply forces

• Free memory (often in destructor of the main GUI form)

The Virtual Device

• Allows you to move your tool in your virtual environment using a mouse instead of a real haptic device

• Forces are calculated in the same way, but are rendered graphically as a vector in the virtual device GUI rather than being applied to the motors of a real device

• Allows you to program and debug on any computer• Moving around

– YZ plane : left button– XY plane : left button and shift or right button

4

CHAI Coordinate Frames

• CHAI natively uses “simulation convention” : Z up, Y right, X out of screen

• MSVC examples position camera looking along negative Z axis and rotate tool to align with “graphics convention” : X up, Y right, Z out of screen

• Borland examples position camera looking along negative X axis and don’t rotate tool, thus using “simulation convention”

• Your choice for your program

Z

X

Y

Y

Z

X

“Simulation Convention” “Graphics Convention”

CHAI Scenegraph Tree

• A cWorld object is the root of the virtual environment; a pointer to this object is given to cViewport, cCamera, and cLight objects

• Objects may be children of other objects (m_parent pointer and m_children vector of pointers)

• Each object has m_localPos / m_localRot and m_globalPos / m_globalRot members

• Global position / rotation for an object and all its children are recalculated when you call computeGlobalPositions(false)

• Force calculations use m_globalPos / m_globalRot• In graphic rendering, the tree is traversed and only m_localPos / m_localRot

are sent to OpenGL, which computes globals automatically

cWorld

cMesh cMesh

cMesh cMesh cMesh

cMeta3dofPointer cShapeSphere

An object implemented as a potential field

Submeshes

A tool that interfaces to a haptic device and is rendered as an avatar

Choosing a compiler and creating a new program

• Choose a compiler and a GUI framework– Borland C++ Builder 6

• Simplest to learn how to make GUIs; nice interface• Many libraries available on-line can’t be used because of incompatible library formats

(could be important for final project)• Not used that much in the real world

– Microsoft Visual Studio 6.0• Produces fast code; widely used; compatible with most on-line libraries• Very steep learning curve for making GUIs; MFC is horrifying

– Microsoft Visual Studio 7 (aka .NET)• Fairly simple to learn how to make GUIs; nice interface• Produces fast code; widely used; compatible with most on-line libraries• Not fully supported in CHAI: project files exist, but they use MFC taken directly from

MSVC 6 examples and don’t use .net framework• Somewhat big and unwieldy; portability problems

– Others: GLUT with any above compiler (see reflections and earth CHAI examples), Linux, Cygwin

• Create new programs– Copy a CHAI example (e.g., basic_shapes) and edit : quick– Create from scratch : fully understand what it’s doing

Step-by-Step : MSVC .net

Video at http://cs277.stanford.edu/msvc2003.avi

Project at http://cs277.stanford.edu/cs277.zipNeed to run on high-resolution monitor (1600x1200 pixels) for video to be clear

Steps : MSVC .net• Download CHAI (http://www.chai3d.org) and unzip to local directory• Launch MSVC .net and start a new Windows Form Application project in chai3d/examples/msvc7

folder• Set the Project->Properties (for All Configurations except as noted; select config in top left drop-down box)

– Set General - Output Directory and Debugging - Working Directory: ../../../bin– Set General - Use of ATL: Dynamic link to ATL– Set C/C++ - General - Additional Include Directories: ../../../include– Set C/C++ - Preprocessor – Preprocessor Defs: WIN32;_WINDOWS;_MSVC;WINVER=0X0500– For Debug Config, set C/C++ - Code Generation - Runtime Libraries: Multi-threaded Debug DLL– For Release Config, set C/C++ - Code Generation – Runtime Libraries: Multi-threaded DLL– Set C/C++ - Language – Enable Run-Time Type Info: Yes– Set Linker – General - Output File: ../../../bin/project_name.exe– Set Linker – General – Additional Library Directories: ../../../lib/msvc7– Set Linker – Input - Additional Dependencies: winmm.lib opengl32.lib chai3d_complete.lib glu32.lib

PhantomDriver.lib atls.lib– Set Linker - Ignore Specific Library: msvcprt.lib libc.lib msvcp60.lib

• Design form (include a panel, a button, and a timer for graphics)– Use the toolbox (View->Toolbox) to add GUI elements (such as buttons) to your form– Use the Properties Box (usually in lower right corner) to edit properties of GUI elements– To create an event callback handler (such as for when a button is clicked), click the lightning button on the

Properties Box, then double-click in space next to the appropriate event • Add code• Build/compile• Run executable

Creating a Program with Borland C++ Builder 6

Video at http://cs277.stanford.edu/bcpp.avi

Project at http://cs277.stanford.edu/cs277_bcpp.zipNeed to run on high-resolution monitor (1600x1200 pixels) for video to be clear

5

Steps : Creating a Program with Borland C++ Builder 6

• Download CHAI (www.chai3d.org) and unzip to local directory• Launch Borland C++ Builder • Save unit and project in a new subfolder in chai3d/examples/bcpp6• Add all the libraries in chai3d/lib/bbcp6 to project• Set the Project->Options (select Directories/Conditionals tab)

– Add to Include path: ../../../include– Set Final output: ../../../bin– Under the Linker tab, check “Use Dynamic RTL”

• Design form (include a panel, a button, and a timer for graphics)– Use the toolbars at the top to add GUI elements (such as buttons) to your form– Use the Object Inspector (usually in lower left corner) to edit properties of GUI elements– To create an event callback handler (such as for when a button is clicked), click the Events Tab on the

Object Inspector, then double-click in space next to the appropriate event

• Add code• Build/compile• Run executable

Copying a MSVC 6 Example

Video at http://cs277.stanford.edu/msvc6.avi

Project at http://cs277.stanford.edu/cs277_msvc6.zipNeed to run on high-resolution monitor (1600x1200 pixels) for video to be clear

Steps : Copying a MSVC 6 Example

• Download CHAI (www.chai3d.org) and unzip to local directory• Copy and paste chai3d/examples/msvc6/basic_shapes folder into

chai3d/examples/msvc6• If you want, download the UCanCode toolbox and use it to

rename the new project (http://www.ucancode.net/Products/free%20product/toolbox.htm)

• Add/change code• Build/Compile• Run executable

Copying a MSVC 7 Project• Copy and paste the folder of the original project into same directory

(such as chai3d/examples/msvc7)• Rename the folder (click, pause, click, and type new name)• Open the new solution file in MSVC7• Select Project->Properties, go to Linker->General tab, and change

the name of the file under Output File• If you want to remove all vestiges of the old project name

• Select File->Save As, and enter the new name for the project• Click on the old project name in the Solution Explorer window,

and rename it (either click-pause-click-type, or using the Properties box below)

• Select File->Save All, and exit• Rename the solution file (click, pause, click, and type new name)• Delete all remaining files in the folder with the old name

The Typical Structure of a CHAI Program• Header file

– #include’s– Variable declarations

• Initialization (often in constructor of the main GUI form)– Create a world, camera, light, and viewport (linked to a window handle from the GUI)– Create objects, specify their material properties, and add them to the world

• Explicitly define the triangles of a cMesh• Load a mesh from a .obj or .3ds file• Derive a subclass of cGenericPotentialField, and create objects of this type

– Initialize timers for graphic and haptic callbacks• Haptics initialization (often in a button click callback)

– Create a tool and add it to the world– Set tool workspace, align coordinate frames, compute global positions– Start tool, set forces on, set callback function for haptic timer

• Graphics callback (~30 Hz)– Render the viewport

• Haptics callback (~1000 Hz)– Read device position (and possibly orientation)– Compute forces– Apply forces

• Free memory (often in destructor of the main GUI form)

Code of a Simple Example Program : Header file• Header file

– #include "CWorld.h"– #include "CViewport.h"– #include "CGenericObject.h"– #include "CPhantom3dofPointer.h"– #include "CMeta3dofPointer.h"– #include "CPrecisionTimer.h"– #include "CLight.h“

– cWorld* world;– cCamera* camera;– cViewport* viewport;– cLight* light;– cMesh* object;– cPrecisionTimer* mm_timer;– int haptics_enabled;– cGeneric3dofPointer* tool;

6

Code of a Simple Example Program : Initialization• Initialization (often in constructor of the main GUI form)

– world = new cWorld();– world->setBackgroundColor(1.0f,1.0f,1.0f);– camera = new cCamera(world);– int result = camera->set(cVector3d(0,0,4), cVector3d(0.0, 0.0, 0.0), cVector3d(0.0, 1.0, 0.0)); – light = new cLight(world);– light->setEnabled(true);– light->setPos(cVector3d(-1, 1, 1));– IntPtr ptr = panel1->get_Handle();– HWND hwnd = (HWND)ptr.ToPointer();– viewport = new cViewport(hwnd, camera, false);– object = new cMesh(world);– object->newVertex(-0.6, -0.6, 0.6);– object->newVertex(0.6, -0.6, 0.6);– object->newVertex(0.6, 0.6, 0.6);– object->newTriangle(0,1,2);– for(int n=0; n<3; n++) {– cVertex* curVertex = object->getVertex(n);– curVertex->setNormal(0,0,1);– }– world->addChild(object);– cMaterial material;– material.setStiffness(50.0);– material.m_ambient.set( 0.8, 0.0, 0.0, 1.0 );– object->m_material = material;– world->computeGlobalPositions(false);– mm_timer = new cPrecisionTimer();– tool = 0;– haptics_enabled = 0;

Code of a Simple Example Program : Haptics initialization• Haptics initialization (often in a button click callback)

– if (haptics_enabled == 0) {– haptics_enabled = 1;– if (tool == 0) {– tool = new cMeta3dofPointer(world, 0, true);– world->addChild(tool);– tool->initialize();– tool->setWorkspace(2.0,2.0,2.0);– tool->rotate(cVector3d(0,0,1),-90.0*3.14159/180.0);– tool->rotate(cVector3d(1,0,0),-90.0*3.14159/180.0);– tool->setRadius(0.05);– }– tool->computeGlobalPositions();– tool->start(); – tool->setForcesON();– mm_timer->set(0,haptic_iteration,tool);– } – else {– haptics_enabled = 0;– mm_timer->stop();– tool->setForcesOFF();– tool->stop();– }

Code of a Simple Example Program : Graphics callback

• Graphics callback (in the callback of a timer, such as one added to the GUI; could also use a cPrecisionTimer as used for the haptic loop)

– if (viewport)– viewport->render();

Code of a Simple Example Program : Haptics callback

• Haptics callback– void haptic_iteration(void* param) {– cGeneric3dofPointer* tool = (cGeneric3dofPointer*)(param);– tool->updatePose();– tool->computeForces();– tool->applyForces();– }

Code of a Simple Example Program : Free memory

• Free memory (often in destructor of the main GUI form)– if (haptics_enabled) {– mm_timer->stop();– tool->setForcesOFF();– tool->stop();– }– if (world) delete world;– if (viewport) delete viewport;– if (camera) delete camera;

A Few Notes and Bugs• When culling is enabled, the “back” of a triangle or other polygon will not

be drawn. The front of the polygon is defined as the side from which the vertices, in the order specified when calling newTriangle(), are counterclockwise. If you set my_mesh->useCulling(false), both sides will always be rendered.

• To compile with MSVC 2005, change m_freeVertices.erase(0); to m_freeVertices.erase(m_freeVertices.begin()); in cMesh::newVertex()

• To compile earth and reflections examples in MSVC, or to use GLUT in your programs, add glut32.lib to dependencies and chai3d/external/OpenGL/msvc6 to library paths (It’s already linked into Graphics library in Borland)

• When using an object of class cShapeSphere, initialize its texture to NULL (or set a texture) before adding it to the world (my_sphere->m_texture = NULL)

• You could also use a cPrecisionTimer for the graphics loop just as for the haptics loop (setting a less frequent callback interval) rather than using the GUI timers

7

Calibrating the Phantom• For the Omnis, if the calibration seems off, just return handle

into its calibration well until it clicks in, then take it back out• For Phantom 1.0/1.5, hold the Phantom in the neutral position

when you first enable haptics when running your program (or every time your program calls tool->initialize())

• For Phantom 1.0/1.5, you may occasionally need to run Dice Demo (found in Start->Programs->SensAble); when it starts, it will ask you to hold it in the neutral position and press Enter.Do this, then play with the die until it feels correct.

Neutral position for 1.0/1.5

(All joint angles 90o)

The Phantom Doesn’t Work!

• Check Phantom Configuration– Found in Control Panels– Make sure correct model (Phantom 1.0,

1.5, or Omni) is selected for first device in drop-down box• Try Dice Demo

– Found in Start->Programs->SensAble– If it doesn’t work, there is either a hardware problem

(check for loose cables and, for Phantom 1.0/1.5, if the watchdog timer (remote switch) is enabled) or a problem in Phantom Configuration

– If it does work, the problem is in software. Try an unmodified CHAI demo; if it doesn’t work, there is a problem with your CHAI set-up; if it does, the problem is with your program

• Can also try Phantom Test (Start->Programs->SensAble)

Documentation• CHAI

– The best documentation is the included examples. Once you’ve chosen which compiler you want to use, look through some of the examples for that compiler, especially basic_shapes and object_loader.

– It’s open source, so look at the header files and even the code inside CHAI. Open the project files in chai3d/msvc6, chai3d/msvc7, or chai3d/bbcp6.

– Getting started guide and doxygen files at http://www.chai3d.org/doc.html

– These slides! And the videos and code linked from the CS277 webpage (announcements section)

• OpenGL– OpenGL Red Book: http://fly.srk.fer.hr/~unreal/theredbook/

• GLUT– http://www.cs.uccs.edu/~semwal/man.html