2017-04-24 1 views
0

객체를 가져와 결과를 반환하기 전에 python으로 처리하기 위해 대기열에서 제외하는 객체 대기열이 있습니다. 나는 그것이 모두 어떻게 어울리는 지에 관해 조금 확신하지 않는다. 그러나 내가 내가 꽤 가깝다라고 생각하는 여러 가지 장소에서 모은 것에서.C++ 객체 인스턴스를 Python 함수에 전달합니다.

class PyData 
{ 
public: 

    PyData(
     const btVector3 &TORSO_LV, 
     std::vector<std::tuple<float, float, float>> DsOsAVs, 
     std::vector<btVector3> RF_FORCES, 
     std::vector<btVector3> LF_FORCES, 
     float slope, 
     float compliance 
     ); 

    std::tuple<float, float, float> m_TORSO_LV; 
    std::vector<std::tuple<float, float, float>> m_DsOsAVS; 
    std::vector<std::tuple<float, float, float>> m_RF_FORCES; 
    std::vector<std::tuple<float, float, float>> m_LF_FORCES; 

    float m_slope; 
    float m_compliance; 


    ~PyData(); 
}; 

후 나는 다음과 같습니다 부스트 파이썬 모듈 생성 :

매 33 밀리 후 나는 PyData 객체를 생성
BOOST_PYTHON_MODULE(pydata) { 
    bp::class_<PyData>("PyData", 
     bp::init< 
      const btVector3, 
      std::vector<std::tuple<float, float, float>>, 
      std::vector<btVector3>, 
      std::vector<btVector3>, 
      float, 
      float 
     >()) 
     .def_readonly("Torso_LV", &PyData::m_TORSO_LV) 
     .def_readonly("DsOsAVs", &PyData::m_DsOsAVS) 
     .def_readonly("RF_FORCES", &PyData::m_RF_FORCES) 
     .def_readonly("LF_FORCES", &PyData::m_LF_FORCES); 
}; 

나는이처럼 보이는 클래스가 그것을 대기열에 넣으십시오. 이런 식으로 뭔가 :

// Check the sample clock for sampling 
    if (m_sampleClock.getTimeMilliseconds() > 33) { 
     if (ContactManager::GetInstance().m_beingUsed) { 
      PyData dat = BuildPyData(); 
      if (dat.m_compliance != 0.0f) { 
       std::unique_lock <std::mutex> l(m_mutex); 
       m_data.push_front(dat); 
       m_NotEmptyCV.notify_one(); 
       l.unlock(); 
      } 
     } 

     m_sampleClock.reset(); 
    } 

내가 다음 객체를 얻고처럼 보이는 파이썬 함수에를 보낼 수있는 큐의 대기를 해제 별도의 작업자 스레드가 : 기본적으로

void ContactLearningApp::PythonWorkerThread() { 

    printf("Start Python thread. \n"); 

    bp::object f = m_interface.attr("predict_on_data"); 

    while (true) { 
     //printf("Inside while loop and waiting. \n"); 
     std::unique_lock<std::mutex> ul(m_mutex); 
     while (m_data.size() <= 0) { 
      m_NotEmptyCV.wait(ul); 
     } 
     PyData dat = m_data.back(); 
     m_data.pop_back(); 

     f(boost::python::ptr(&dat)); 

     ul.unlock(); 
     //m_ProcessedCV.notify_one(); 
     //bp::exec("print ('Hello from boost')", m_main_namespace); 
    } 

} 

을, 나는 노력하고 있어요 파이썬 인수로 C++에서 인스턴스화 된 객체를 전달할 수 있지만 함께 조각하는 방법을 모르겠습니다. 파이썬 인터프리터는 객체의 복사본을 필요로하지 않으므로 boost :: python :: ptr을 사용하고 있습니다. 파이썬 파일을 간단하고 난 그냥 객체가이 같은 콘솔에 접수를 인쇄하려면 :

def predict_on_data(data): 
    print("In Predict on Data") 
    print(data) 

나는이 부스트 모듈과 통합하는 방법을 모르겠어요. 이 작업을 수행하는 올바른 방법은 무엇입니까?

답변

0

저는 PyData 데이터 객체를 기반으로 몇 가지 샘플 코드를 작성했습니다. 이 코드는 원래의 용도대로, 파이썬에/데이터를 교환하기위한 부스트 :: 파이썬 데이터 구조 (튜플 및 목록)를 사용하지만 이들은 표준 : : 튜플 및 표준 : : 벡터에서 그들에 데이터를 복사하여 채울 수 있습니다 필요에 따라.

이것은 파이썬 2.7 및 부스트 1.53에서 작동합니다. 잘하면이 도움을 사용할 수 있습니다. 주의 : Py_Initialze() 후에 initpydata() (생성 된 함수)에 대한 호출이 필요합니다.

C++ 코드 :

#include <iostream> 
#include <vector> 
#include <tuple> 
#include <boost/python.hpp> 
#include <boost/python/list.hpp> 

class PyData 
{ 
    public: 

    PyData() {} 

    float m_slope; 
    float m_compliance; 

    boost::python::tuple m_TORSO_LV; 
    boost::python::list  m_DsOsAVS; 
    boost::python::list  m_RF_FORCES; 
    boost::python::list  m_LF_FORCES; 

    void InitData() 
    { 
     // simulate setting up data 
     m_slope = 1.0; 
     m_compliance = 2.0; 

     m_TORSO_LV = boost::python::make_tuple(3.0, 4.0, 5.0); 

     m_DsOsAVS.append(boost::python::make_tuple(10.0, 11.0, 12.0)); 
     m_DsOsAVS.append(boost::python::make_tuple(20.0, 21.0, 22.0)); 

     // etc. 
    } 

    ~PyData() {} 
}; 

BOOST_PYTHON_MODULE(pydata) { 
boost::python::class_<PyData>("PyData") 
    .def_readwrite("Torso_LV", &PyData::m_TORSO_LV) 
    .def_readwrite("DsOsAVs", &PyData::m_DsOsAVS) 
    .def_readwrite("RF_FORCES", &PyData::m_RF_FORCES) 
    .def_readwrite("LF_FORCES", &PyData::m_LF_FORCES) 
    .def_readwrite("slope", &PyData::m_slope) 
    .def_readwrite("compliance", &PyData::m_compliance) 
    ; 
}; 

int main (int argc, char * argv[]) 
{ 
    Py_Initialize(); 

    initpydata(); 

    boost::python::object main=boost::python::import("__main__"); 
    boost::python::object global(main.attr("__dict__")); 
    boost::python::object result = boost::python::exec_file("/home/andy/Python2.py", global, global); 
    boost::python::object predict_on_data = global["predict_on_data"]; 
    if (!predict_on_data.is_none()) 
    { 
     boost::shared_ptr<PyData> o(new PyData); 
     o->InitData(); 
     predict_on_data(boost::python::ptr(o.get())); 
     std::cout << "values in c++ object are now: " << o->m_slope << " and " << o->m_compliance << std::endl; 
    } 

    return 0; 
} 

파이썬 코드 (이 예에서는 Python2.py 파일) :

def predict_on_data(o): 
    print "In Python:" 
    print repr(o) 
    # print the data members in o 
    print "o.slope is " + repr(o.slope) 
    print "o.compliance is " + repr(o.compliance) 
    print "o.Torso_LV is " + repr(o.Torso_LV) 
    print "o.m_DsOsAVs is " + repr(o.DsOsAVs) 
    # modify some data 
    o.slope = -1.0 
    o.compliance = -2.0 

일단이 같은 출력을 제공해야 실행 :

In Python: 
<pydata.PyData object at 0x7f41200956e0> 
o.slope is 1.0 
o.compliance is 2.0 
o.Torso_LV is (3.0, 4.0, 5.0) 
o.m_DsOsAVs is [(10.0, 11.0, 12.0), (20.0, 21.0, 22.0)] 
values in c++ object are now: -1 and -2 

희망 이것은 유용합니다.

+0

initpydata() 함수를 찾을 수 없습니다. 나는 문서가 initname()과 init_module_name()을 생성한다고 말하기 때문에 자동으로 생성된다는 것을 알고있다. init_module_pydata()를 찾을 수 있습니다. 그들은 똑같은가요? init_name은 C++에서 handle_exception()에 init_module_name을 전달하는 것처럼 보입니다. (매크로를 통해) 생성 및 BOOST_PYTHON_MODULE (pydata)로 시작하는 코드 블록으로 범위를하게된다 initpydata() 함수 내 예에서 C++ 코드에서 – terminix00

+0

{- 코드에서이 있나요? 그렇다면 거기에 있어야합니다. –

관련 문제