ソースを参照

change modulecommpython,test ok.

yuchuli 5 ヶ月 前
コミット
2fa41c6b6f

+ 91 - 0
src/common/modulecomm/PyModuleCommModule.py

@@ -0,0 +1,91 @@
+
+import threading  
+import time  
+
+import modulecommpython
+import numpy as np  
+
+
+modulelock = threading.Lock()  
+nThread = 0
+  
+class PyModuleComm:  
+    def __init__(self,strname):  
+        # 初始化代码...  
+        print("name: ",strname)
+        self.strmemname = strname
+        self.mbRegister = False
+        global nThread
+        nThread = nThread+1
+        self.mnMode = 0
+        print("nThread = ",nThread)
+        self.obj = modulecommpython.get_ca_object()
+        pass  
+
+    def RegisterRecv(self,call):
+        if self.mbRegister:
+            print(" Have register, can't register other.")
+            return
+        print("Register: ",self.strmemname)
+        self.mpcall = call
+        self.mbRegister = True
+        self.mbRun = True
+        self.mpthread = threading.Thread(target=self.threadrecvdata, args=(self.strmemname,))  
+        self.mpthread.start()
+        print("complete create thread.")
+        self.mnMode = 1
+        self.obj.RegisterRecv(self.strmemname)
+
+    def RegiseterSend(self,nSize,nPacCount):
+        if self.mbRegister:
+            print(" Have register, can't register other.")
+            return
+        print("Register: ",self.strmemname)
+        self.mnsize = nSize
+        self.mnPacCount = nPacCount
+        self.mbRegister = True
+        self.mnMode = 2
+        self.obj.RegisterSend(self.strmemname,nSize,nPacCount)
+    
+    def SendData(self,arr,nsendsize):      
+        nrealsize = np.zeros(1, dtype=np.int32)  
+        nrtn = self.obj.SendData(arr,nsendsize,nrealsize)
+  
+    def threadrecvdata(self, arg):  
+        # 这个函数将被线程执行  
+ #       print(f"线程开始执行,参数是 {arg}")  
+        nBuffSize = 1000
+        arr = np.zeros(nBuffSize,dtype=np.int8)
+        recvtime = np.zeros(1,dtype=np.int64)
+        nrealsize = np.zeros(1,dtype=np.int32)
+        while 1:
+            nrtn = self.obj.RecvData(arr,nBuffSize,nrealsize,recvtime)
+            if nrtn > 0:
+                self.mpcall(arr,nrtn,recvtime)
+            else:
+                pass
+            if nrtn < 0:
+                nBuffSize = nrealsize[0] * 2
+                arr = np.zeros(nBuffSize,dtype=np.int8)
+            else:
+                time.sleep(0.001)
+            
+        print("threadrecvdata complete.")
+
+    def stop_thread(self):
+        self.mbRun = False
+        self.mpthread.join()
+  
+    def start_thread(self, arg):  
+        # 创建线程对象,target参数指向要在线程中运行的函数  
+        self.mbRun = True
+        self.mpthread = threading.Thread(target=self.my_function, args=(arg,))  
+          
+        # 启动线程  
+        self.mpthread.start()  
+          
+        # 可以在这里添加其他代码,主线程会继续执行  
+        print("主线程继续执行...")  
+  
+        # 如果需要等待线程结束,可以调用 join() 方法  
+        # thread.join()  

+ 253 - 0
src/common/modulecomm/modulecommpython.cpp

@@ -0,0 +1,253 @@
+#include <boost/python.hpp>  
+#include <boost/python/numpy.hpp>  
+
+#include <boost/thread.hpp>
+
+#include <boost/signals2.hpp>
+
+#include <iostream>
+#include <thread>
+#include <chrono>
+
+#include <Python.h>  
+#include <string>
+#include <mutex>
+
+#include "modulecomm.h"
+  
+using namespace boost::python;  
+
+  
+namespace py = boost::python; 
+namespace np = boost::python::numpy;  
+
+// 回调函数类型  
+
+
+boost::signals2::signal<void(int)> mySignal; 
+py::object  mpfunc; 
+
+void onSignal(int value) {  
+
+        std::cout << "Member function slot called with value: " << value << std::endl;  
+ //   mpfunc(39);
+
+}  
+  
+// 假设我们有一个简单的C++函数,它返回一个整数  
+class ModuleCommPython
+{
+private:
+    std::thread * mpthread;
+    std::string mstrmemname;
+    void * mpa = nullptr;
+
+    std::shared_ptr<char> mpdata_ptr;
+    int mnRecvdatasize = 0;
+    bool mbUpdate = false;
+    int64_t mnRecvTime = 0;
+    bool mbRun = true;
+
+    std::mutex * mpmutex;
+    
+public:
+	ModuleCommPython(){
+        mpa = nullptr;
+  //      mpthread = new std::thread(&ModuleCommPython::threadcallback,this);
+        mpmutex = new std::mutex();
+        std::cout<<"create trhead."<<std::endl;
+    }
+	~ModuleCommPython(){
+        std::cout<<" delete ModuleCommPython"<<std::endl;
+        if(mpa != nullptr)
+        {
+            std::cout<<" delete mpa"<<std::endl;
+            iv::modulecomm::Unregister(mpa);
+        }
+        mbRun = false;
+ //       mpthread->join();
+        std::cout<<" complete ModuleCommPython"<<std::endl;
+    }
+
+    void Release()
+    {
+        std::cout<<" delete ModuleCommPython"<<std::endl;
+        if(mpa != nullptr)
+        {
+            std::cout<<" delete mpa"<<std::endl;
+            iv::modulecomm::Unregister(mpa);
+        }
+        mbRun = false;
+ //       mpthread->join();
+        std::cout<<" complete ModuleCommPython"<<std::endl;
+    }
+
+
+
+    void TestCall()
+    {
+        static int x =0;
+        x++;
+        mpfunc(x);
+    }
+
+    void SetCall(py::object xfun)
+    {
+        
+        mpfunc = xfun;
+    }
+
+    void SetMemName(const std::string& strmemname)
+    {
+        mstrmemname = strmemname;
+        
+    }
+
+    void RegisterSend(const std::string& strmemname,int ndatasize,int npacsize)
+    {
+        std::cout<<"register send."<<std::endl;
+        mpa = iv::modulecomm::RegisterSend(strmemname.data(),ndatasize,npacsize);  
+    }
+
+    void RegisterRecv(const std::string& strmemname)
+    {
+        std::cout<<"register recv."<<std::endl;
+        ModuleFun funRecv =std::bind(&ModuleCommPython::UpdateRecv,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3,std::placeholders::_4,std::placeholders::_5);
+        mpa = iv::modulecomm::RegisterRecvPlus(strmemname.data(),funRecv);
+    }
+
+    int SendData(np::ndarray& arr,int ndatasize)
+    {
+        std::cout<<"data size is: "<<ndatasize<<std::endl;
+        void* data = arr.get_data();  
+        char* data_ptr = static_cast<char*>(data);
+        iv::modulecomm::ModuleSendMsg(mpa,data_ptr,ndatasize);
+        return 0;
+    }
+
+
+    int RecvData(np::ndarray& arr,int ndatasize, np::ndarray& nRealSize,np::ndarray& ndRecvTime)
+    {
+        int nRtn = 0;
+        if(mbUpdate == false)
+        {
+            return nRtn; //no data recv
+        }
+        
+        mpmutex->lock();
+        if(ndatasize < mnRecvdatasize)
+        {
+            void* data = nRealSize.get_data();  
+            int* data_ptr = static_cast<int*>(data);  
+            data_ptr[0] = mnRecvdatasize;
+            nRtn = -1;
+        }
+        else
+        {
+            void* data = arr.get_data();  
+            char* data_ptr = static_cast<char*>(data);
+            memcpy(data_ptr,mpdata_ptr.get(),mnRecvdatasize);
+
+            int64_t nRecvTime = std::chrono::system_clock::now().time_since_epoch().count();
+
+            void* datatime = ndRecvTime.get_data();  
+            int64_t* datatime_ptr = static_cast<int64_t*>(datatime);
+            ndRecvTime[0] = nRecvTime;
+
+            nRtn = mnRecvdatasize;
+            mbUpdate = false;
+        }
+        mpmutex->unlock();
+
+        return nRtn;
+        
+    }
+
+    void UpdateRecv(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
+    {
+        (void)index;
+        (void)dt;
+        (void)strmemname;
+ //       std::cout<<"recv data."<<std::endl;
+        if(nSize == 0)return;
+        mpmutex->lock();
+        mpdata_ptr = std::shared_ptr<char>(new char[nSize]);
+        memcpy(mpdata_ptr.get(),strdata,nSize);
+        mnRecvdatasize = nSize;
+        mbUpdate = true;
+        mpmutex->unlock();
+    }
+
+	int Add(np::ndarray& arr) {  
+	int nsize = 0;
+	std::cout<<"enter add."<<std::endl;
+ //   std::cout << "Shape: "<< py::extract<std::string>(arr.attr("shape")) << std::endl;  
+ //   std::cout << "Data type: "<< py::extract<std::string>(arr.attr("dtype")) << std::endl;  
+  
+    // 获取数组的维度  
+    const np::dtype& dtype = arr.get_dtype();  
+    const Py_intptr_t* shape = arr.get_shape();  
+    int ndims = arr.get_nd();  
+
+    nsize = ndims;
+  
+    // 获取指向数据的指针  
+    void* data = arr.get_data();  
+    
+    std::cout<<" size: "<<nsize<<std::endl;
+  
+    // 根据数据类型处理数据  
+    if (dtype == np::dtype::get_builtin<unsigned char>()) {  
+        unsigned char * data_ptr = static_cast<unsigned char*>(data);  
+        for (Py_intptr_t i = 0; i < 5; ++i) {  
+            std::cout << (int)(data_ptr[i]) << " "<<std::endl;
+        }  
+        data_ptr[2] = 100;
+        std::cout << std::endl;  
+    } else {  
+        std::cerr << "Unsupported data type" << std::endl;  
+    }   
+    return nsize;
+    }
+
+    void threadcallback()
+    {
+        mySignal.connect(boost::bind(onSignal, _1));  
+        while(mbRun)
+        {
+            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
+            std::cout<<"thread run "<<std::endl;
+            mySignal(1);
+
+        }
+    }
+
+    std::string teststring(const std::string & str)
+    {
+        return str + "hello, change this string.";
+    }
+};
+
+// 包装函数,将C++整数转换为boost::python::object并返回  
+boost::python::object get_ca_object() {  
+    ModuleCommPython * pca = new ModuleCommPython();  
+    return py::object(*pca);  
+}  
+  
+// 注册模块和函数  
+BOOST_PYTHON_MODULE(modulecommpython) {  
+    using namespace boost::python;
+    np::initialize();  
+    class_<ModuleCommPython>("ModuleCommPython")  
+        .def("Add", &ModuleCommPython::Add)
+        .def("SetCall",&ModuleCommPython::SetCall)  
+        .def("TestCall",&ModuleCommPython::TestCall)
+        .def("SendData",&ModuleCommPython::SendData)
+        .def("RecvData",&ModuleCommPython::RecvData)
+        .def("RegisterSend",&ModuleCommPython::RegisterSend)
+        .def("RegisterRecv",&ModuleCommPython::RegisterRecv)
+        .def("teststring",&ModuleCommPython::teststring)
+        ;   
+    def("get_ca_object", &get_ca_object);  
+}
+  

+ 21 - 20
src/common/modulecomm/test.py

@@ -2,38 +2,39 @@ import modulecommpython
 import numpy as np  
 import time
 
-from PyModuleComm import PyModuleComm
-  
+import gpsimu_pb2
 
-def my_python_callback(value):  
-    print("Python callback function called from C++!. value: ",value)  
+from PyModuleCommModule import PyModuleComm
 
-def main():  
-    arr = np.array([1, 2, 3, 4, 5], dtype=np.uint8) 
-    obj = modulecommpython.get_ca_object()
-    obj.SetCall(my_python_callback)
-    print("obj")
 
-    result = obj.Add(arr) 
+import pickle 
+  
 
-    print(result)  # 输出: 5
+def my_python_callback(arr : np,nsize,time):  
+    print("Python callback function called from C++!. time: ",time)
+    print("    size: ",nsize)  
+    sub_arr = arr[0:nsize]
+    databytes = sub_arr.tostring()
+    msg = gpsimu_pb2.gpsimu()
+    msg.ParseFromString(databytes)
+    print("lon: ",msg.lon)
+    
+
+      
+    
+
+def main():  
 
-    print("np2 : ",arr[2])
     # 初始化一个变量  
     count = 0  
 
     mc = PyModuleComm("hcp2_gpsimu")
-    mc.RegiseterSend(1000,1)
-
-  
+    mc.RegisterRecv(my_python_callback)
+ 
     # 使用while循环,只要count小于10,就继续循环  
     while count < 10:  
         time.sleep(1.0)
-        obj.TestCall()
-        arr = np.zeros(1000, dtype=np.uint8)  
-        mc.SendData(arr)
- #       print(f"当前计数是: {count}")  
- #       count += 1  # 每次循环,增加count的值  
+
   
     print("循环结束!")