-
Notifications
You must be signed in to change notification settings - Fork 1
How to send more data to python
evanrex edited this page Jun 7, 2021
·
11 revisions
- To see these techniques in use view Strategy.cc. the pyFunction.
- the first command that must be run before using or calling python Scripts or PyObjects is Py_Initialize(). this function basically creates a python interpreter to run python commands and files
- to run a python command use the following command PyRun_SimpleString("import os"). in this example here we are importing the os library to interpreter.
- this is an example on how you can call on a python file. to check if it has imported you can put pModule in an if statement
//calling on myFile.py
PyObject * pName = PyUnicode_FromString("myFile");
PyObject * pModule = PyImport_Import(pName);
if(pModule)
{
// running the method myFunc in myFile.py
PyObject * pFunc = PyObject_GetAttrString(pModule, "myFunc");
if(pFunc && PyCallable_Check(pFunc))
{
//here we call on the python function and store the output in a PyObject in this example we are sending in a list so we attach an O before world_data
PyObject * pReturn = PyObject_CallFunction(pFunc,"O",world_data);
//here we convert the pyobject to the relevent c++ format
int x = (int) PyLong_AsLong(pReturn);
return x;
}
else
{
cout << "ERROR: function selectSkill()\n"<<endl;
return -1;
}
}
else
{
cout << "ERROR: Module not imported"<<endl;
return -2;
}for info on how to convert c++ to PyObject look here and how to convert from PyObject to c++ you can look here
- an example of converting a c++ data type to a python Object
//converting an integer to a PyObject
int x = 5
PyObject * temp;
temp = Py_BuildValue("i",x);- an example of extracting data from a PyObject
PyObject * objectPy;
//update objectPy
int x = (int) PyLong_AsLong(objectPy);- how to define a python list
int n = 5;
PyObject* pyList = PyList_New(n);- how to get an item from the pyList (get the item at index 0)
PyObject* item = PyList_GetItem(pyList, 0);- how to set an item in a python list
int value = 5;
PyObject * item = Py_BuildValue("i",value);
PyList_SetItem(PyList,0,item);In strategy.cc, there is a method: worldData(), which takes in a series of PyObjects, and returns them as a list. It is this list, world_data, that is passed through to python.
PyObject * world_data = worldData(playerNumPy,playModePy,sidePy,posPy,ballPy, teamPositionsPy, oppPositionsPy ,teamDistToBallPy,OppDistToBallPy);
n = pyFunction(world_data,pos);worldData()
PyObject * worldData(PyObject * _playerNumber,PyObject * _playMode,PyObject * _side,PyObject * posPy,PyObject * ballPy,PyObject * teamPositionsPy,PyObject * oppPositionsPy,PyObject * teamDistToBallPy,PyObject * OppDistToBallPy){
//this mirrors constructor for Robocup class on python side
PyObject * pyList;
pyList = PyList_New(9);
PyList_SetItem(pyList,0,_playerNumber);
PyList_SetItem(pyList,1,_playMode);
PyList_SetItem(pyList,2,_side);
PyList_SetItem(pyList,3,posPy);
PyList_SetItem(pyList,4,ballPy);
PyList_SetItem(pyList,5,teamPositionsPy);
PyList_SetItem(pyList,6,oppPositionsPy);
PyList_SetItem(pyList,7,teamDistToBallPy);
PyList_SetItem(pyList,8,OppDistToBallPy);
return pyList;Robocup constructor:
class Robocup():
//...
def __init__(self, world_data):
"""
Parameters
----------
world data passed through to selectSkill() - ALTERATION IS NOT RECOMMENDED
This mirrors worldDate object on C++ side
"""
#World Model Data:
self.__player_number=world_data[0]
self.__play_mode=world_data[1]
self.__side = world_data[2]
self.__player_pos = world_data[3]
self.__ball_pos = world_data[4]
self.__team_positions = world_data[5]
self.__opponent_positions = world_data[6]
#Wrapped C++ Functions:
self.__team_dist_ball = world_data[7]
self.__opp_dist_ball = world_data[8]As you can see, the constructor for the Robocup class in python clearly mirrors the method for worldData in C++.