Department of Computer Science



The

INTERACTIVE ROBOTIC ENVIRONMENT

or:

The IRE

by

Andrew LaMora

Christopher Abidin

for

Computer Integrated Surgery II

Spring 2004

TABLE OF CONTENTS

1. Abstract

2. Systems Analysis

a. Current challenges

b. CISST libraries

3. A Solution: Python, SWIG, wxPython

a. Python and C Extension

b. Simple Wrapping Interface Generator (SWIG)

c. Modifications to SWIG

d. wxWindows

4. Results

a. Deliverables

b. Delivered vs. Planned

c. Management

5. Conclusion

6. Acknowledgements

7. References

8. Appendix

ABSTRACT

The IRE is a high level, extensible, object-orientated, cross-platform and Python-based scripting environment for online interaction with Medical robots and imaging devices. It provides access to lower-level C++ libraries wrapped for Python, and via a custom Object Registry permits users to interrupt an executing C++ application to interact with run-time data and objects via a command interpreter. The IRE may be used to develop complete, robust robot applications, and may also be used to debug or interact with existing applications.

SYSTEMS ANALYSIS

Current Challenges

The inspiration for the IRE is to address certain issues with the ERC/CISST robot and tracker libraries. The ERC pursues a computer integrated medical environment through a number of modalities; there are optical and electromagnetic trackers for measuring the motion of tools and doctors, there are slave and autonomous robots for surgical assistance, and there are code libraries for efficiently solving complex problems in robot kinematics and image analysis.

Each modality tends to be addressed by its own library. Although the development of these libraries is peer-supervised and built according to a set of standards, integration remains non-trivial. Application development and robot applications face several challenges:

• No scripting capability

• No command line interface utilities

• No standard debugging environment

• Complex robot configuration scripts are incomprehensible

• Library integration too complex for rapid integration

• Too much is asked of non software professionals for development of simple applications

[pic]

Figure 1: Typical ERC Application

CISST Libraries

The ERC/CISST libraries are currently under revision. These new libraries are based on previous versions, but are built according to a more formal architecture, by software experts, and are optimized for efficency. Decisions made for the architecture of these libraries also apply to all new development; therefore any contributions to the ERC libraries must be cogent of these standards, and must fit neatly within the existing framework. Also, methods employed to increase processing efficiency have resulted in the use of somewhat advanced C++ features, including heavy templating and in-line code. The complexity of these methods and the C++ tools they employ are relevant concerns for the IRE in two ways 1) a scripting language must be compatible with the features employed and 2) the method or utility used to wrap these classes must also support their features.

CHRIS – WRITE MORE STUFF HERE SO THIS FIGURE CAN BE INCLUDED. WHATEVER.

[pic]

A SOLUTION: Python, SWIG, and wxPython

After investigating several possible languages and approaches, we chose Python for our scripting environment, the Simple Wrapping Interface Generator (SWIG) for wrapping C++ libraries, and wxPython for developing the workspace environment. These technologies are explored below:

Python

Python is a dynamically (but nevertheless strongly) typed, object-orientated, interpreted programming language.

CHRIS – MORE STUFF ON PYTHON

The Python library itself provides methods for embedding Python in C, and extending C for Python. This latter property is particularly useful to the IRE, and is used extensively by SWIG to expose C/C++ functionality to Python.

SWIG

SWIG is a wrappering utility designed to expose public C++ methods and data members to a number of higher-level languages, including Python, Perl and TCL. It is both simple and quite powerful. To use SWIG, one writes an interface file (see figure XXXXX), runs the SWIG utility, which produces an interface wrapper that employs the language extension features of the target language. The code to be wrapped is then recompiled to include this new file.

%module example

%{

/* Includes the header in the wrapper code */

#include "header.h"

%}

/* Parse the header file to generate wrappers */

%include "header.h"

Figure XXXX: a SWIG Interface File

SWIG provides directives for modifying the interface file, in addition to a method for including code directly in the output wrapper file. These features are employed by the IRE to address specific needs of the CISST libraries. For instance, the sub-templated classes of cisstVector are not automatically wrapped by SWIG. This problem was solved by defining macros in the SWIG interface to create an instantiation of the templated classes for us; thus allowing SWIG to detect and wrap them. Figure XXXX illustrates this method.

CISSTVECTOR_INSTANTIATE(vctDouble2, double, 2, 1);

CISSTVECTOR_INSTANTIATE(vctDouble3, double, 3, 1);

CISSTVECTOR_INSTANTIATE(vctDouble4, double, 4, 1);

CISSTVECTOR_INSTANTIATE(vctDouble5, double, 5, 1);

CISSTVECTOR_INSTANTIATE(vctDouble6, double, 6, 1);

CISSTVECTOR_INSTANTIATE(vctInt2, int, 2, 1);

CISSTVECTOR_INSTANTIATE(vctInt3, int, 3, 1);

CISSTVECTOR_INSTANTIATE(vctInt4, int, 4, 1);

CISSTVECTOR_INSTANTIATE(vctInt5, int, 5, 1);

CISSTVECTOR_INSTANTIATE(vctInt6, int, 6, 1);

Figure XXXXX: Instantiating Templated Classes

SWIG/Python Object Register

The keystone to the IRE structure is the Object Register. Providing a portal to live memory in an executing C++ application, the Object Register exposes C++ pointers to Python via SWIG, which casts the pointers to the appropriate Python type. In pursuit of ideal usability, the Object Registry must address the general case, and be as type flexible as possible; that is, it should be able to register objects of any type allowed by the application. To accomplish this, void pointers are the obvious choice. Thus the Object Register faces three particular challenges: 1) determining and recording the type of an object in C++, 2) recovering that type in the SWIG interface code and 3) correctly “casting” the pointer to the proper Python type (which is itself defined by a SWIG wrapper).

Several methods were considered for addressing these challenges, and some are discussed in more detail in the next section. In the current solution, we are solving the first issue with a two pronged approach; users may register an object explicitly, by providing the object name, class name and pointer, or by providing simply the object name, and a pointer to an object derived from a common base class (in this case, cmnDataObject; please refer to the ERC library documentation for details on cmnDataObject).

To address the second and third issues, we do two things 1) borrow and redefine (as RegisterGet()) a method from SWIG to explicitly “cast” void pointers based on class types provided as strings, and 2) make a small modification to the SWIG output to correct for changes that SWIG makes to type names. We should note that this “cast” is in fact a look-up and string assignment operation; SWIG performs a simple linear search of type strings, and creates a formatted string to communicate type. For an illustration of these steps, please consider Figures xxx1, xxx2 and xxx3. Figure 1 illustrates the custom interface file; Figure 2 the default SWIG output of a small portion of the register wrapper; and Figure 3 illustrates the necessary modification.

Finally, Figure xxxxxx4 demonstrates the steps necessary to compile the register for every application. The Register library is included and linked–to by any application that desires to export IRE functionality to Python. The library and application code must be recompiled as a shared library (DLL or .so).

#define CISST_EXPORT

%module cmnObjectRegister

%include "F:\cisst\libs\wrapping\cisstVector.swig"

//%include "F:\cisst\libs\include\cisstVector\vctTypes.h"

%{

#include "cmnObjectRegister.h"

typedef vctFixedSizeVector vctDouble3andy;

void Query(const char *name) {

swig_type_info *ty = swig_type_list;

while (ty) {

std::cout name && (strcmp(name,ty->name) == 0)) return ty;

ty = ty->prev;

}

}

PyObject* RegisterGet(char* objectName) {

PyObject* result = NULL;

//* baseObject = (cmnObjectRegister::GetEntry(objectName))->Object;

void* baseObject = (cmnObjectRegister::GetEntry(objectName));//->Object;

if (baseObject == NULL) {

PyErr_SetString(PyExc_NameError, "This object is not registered. Try cmnObjectRegister.List()");

return NULL;

} else {

//std::string className = "_p_" + myRegister::GetClassName(objectName);

std::string className = "_p_" + (cmnObjectRegister::GetEntryName(objectName));//->ClassName;

std::cout ................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download