[[Tutorial]]

Up:[[Tutorial]]         Next:

#contents

*  Before making the first application [#n3a8e766]
** Header files [#oaef0b1e]

We will use the static boost::python library (libboost_python.a) and the dynamic version of the Python library (libpython.so). We will change the path in the Makefile to point to your boost installation directory.

Let’s get some code running. You’ll need to include the correct headers, as you might imagine.

#highlight(c++){{

  #include <boost/python.hpp>
  #include <Python.h>
  #include <dlfcn.h>

}}


These header files are added in the beginning of the program as usual. 

** Initalize Python Interpreter [#k311635f]

Add namepaces:


#highlight(c++){{

    namespace py = boost::python;
    using namespace std;


}}




Then move to the member function onInit()and add the following lines.

#highlight(python){{

    Py_Initialize();
    py::object main_module = py::import("__main__");
    py::object main_namespace = main_module.attr("__dict__");

}}

Note that you must initialize the Python interpreter directly (line 1). After initializing, the __main__ module is imported and the namespace is extracted. This results in a blank canvas upon which we can then call Python code, adding modules and variables.

Note: The initialization of interpreter, import of __main__ module and namespace is independent of the member functions that are first used in. Thus you can do this in some other member function like onAction() which is a loop function in Sigverse. The only requirement is that they should be used before using any python functionality. Also, you dont have to use loop/loop functions to initialize the interpreter. 

Thus, its recommended to initialize the interpreter inside onInit() member function.

#highlight(python){{

    Py_Initialize();
  
}} 


We need to add the following code before initializing the interpreter. The reason for this is explained in FAQ section and is not really important for this tutorial. 

#highlight(c++){{

     dlopen("libpython2.7.so", RTLD_LAZY | RTLD_GLOBAL);  
}} 

We had already included the header file for the above function.  
#highlight(python){{

     #include <dlfcn.h>
}}

Thus, to begin with for all cases we need to have following two lines. 

#highlight(python){{

     dlopen("libpython2.7.so", RTLD_LAZY | RTLD_GLOBAL);  
     Py_Initialize();
}} 

*The first application [#m805ead3]
**Hello World [#v0c3e8c7]

Go to onInit() member function and copy the following:

#highlight(python){{

    Py_Initialize();
    py::object main_module = py::import("__main__");
    py::object main_namespace = main_module.attr("__dict__");

}} 

The blank canvas is created upon which we can call python code now, add modules and variables.

#highlight(python){{

    Py_Initialize();
    py::object main_module = py::import("__main__");
    py::object main_namespace = main_module.attr("__dict__");

}} 



#highlight(python){{

    py::exec("print 'Hello, world'", main_namespace);
    py::python::exec("print 'Hello, world'[3:5]", main_namespace);
    py::exec("print '.'.join(['1','2','3'])", main_namespace);

}}

The 'exec' function runs the arbitrary code in the string parameter within the specified namespace. All of the normal, non-imported code is available. Of course, this isn’t very useful without being able to import modules and extract values. But this will be target of our next tutorial. Now let's execute this program.

* Creating Makefile. [#de4d77a8]


#highlight(c){{

#sigverse header
SIG_SRC  = $(SIGVERSE_PATH)/include/sigverse

#all: $(OBJS)

CC		= gcc
CPP     = g++
AS		= as
LD		= g++
AR		= ar
RANLIB	= ranlib
OBJCOPY	= objcopy

# external libraries and headers

# change the next line to point to the location of your boost installation
EXTERN_DIR =    $HOME/pool
EXTERN_LIBDIR = $(EXTERN_DIR)/lib
EXTERN_INCDIR = $(EXTERN_DIR)/include
EXTERN_BINDIR = $(EXTERN_DIR)/bin

BOOST_PYTHON_LIB = $(EXTERN_LIBDIR)/libboost_python.a

INCDIRS = . 
INCDIRS += $(EXTERN_INCDIR)
#   you may also need to change this directory if you want to pin to a specific
#   python version
INCDIRS += /usr/include/python2.7
INCDIRS += /usr/lib/python2.7/dist-packages/numpy/core/include

INCDIR = $(foreach dir, $(INCDIRS), -I$(dir))

%.o: %.cpp
	$(CPP) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ 

#specifying of object file
OBJS = NameOfController.so 
HWOBJS= hello_world.o 

all: $(OBJS) helloworld

#  you need to change the name of your controller.

NameOfController.so : NameOfController.cpp 
	g++ -DCONTROLLER -DNDEBUG -DUSE_ODE -DdDOUBLE  -I$(SIG_SRC) -I$(SIG_SRC)/comm/controller -I$(INCDIR) -fPIC -shared -o $@ $^ $(LDFLAGS) -L$(EXTERN_LIBDIR) -lboost_python -lpython2.7 

#$^ , $+	The names of all the prerequisites, with spaces between them. 
# The value of $^ omits duplicate prerequisites, 
# while $+ retains them and preserves their order



clean:
	rm -rf *.so *.o $(HWOBJS) hello_world



}}


Then type on console to compile the code:

     $make 


Now, you need to set the library path using.


#highlight(c){{

export LD_LIBRARY_PATH=$HOME/pool/lib

}}


Then, load the xml file using sigviewer:

     $sigserver.sh -w ./WorldFile.xml 

After the world loads, push "Start Button" to see the results of python code. 






#highlight(end)

Up:[[Tutorial]]     Previous:[[Samples/Communication between agents]]     Next:

Front page   Edit Diff Backup Upload Copy Rename Reload   New List of pages Search Recent changes   Help   RSS of recent changes