ROS工程中C++调用python函数
Posted lwlv
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ROS工程中C++调用python函数相关的知识,希望对你有一定的参考价值。
在ROS api程序中,大部分函数的实现是用的python,python语言简单易学,特别做一些测试和调试非常简单。
因此,在C++中调用python函数会极大地减少工作量。
在C++中调用python函数
C++调用python函数,python中用有Python.h头文件起到了很大作用。相关的函数介绍可在 Extending Python with C or C++ 中找到。(这个是针对python2.7的说明)。
在ros工程中,需在CMakeLists.txt中添加相关依赖项即可,关键代码如下:
link_directories(/usr/lib/python2.7/config-i386-linux-gnu)
include_directories($catkin_INCLUDE_DIRS /usr/include)
add_executable(test src/test.cpp)
target_link_libraries(test $catkin_LIBRARIES python2.7) //用于找到libpython2.7.so库
关于C++部分代码如下:
#include <ros/ros.h>
#include <iostream>
#include <python2.7/Python.h>
int main()
Py_Initialize();
PyRun_SimpleString("print 'test simple demo'");
//load python functions
PyRun_SimpleString("import sys");
std::string dirs = std::string("sys.path.append('/home/user/test/')");
PyRun_SimpleString(dirs.c_str());
//load module
PyObject *module = PyString_FromString("for_test");
PyObject *pyModule = PyImport_Import(module);
if(!pyModule) //failed
std::cout << "Get python module failed." << std::endl;
return 0;
//load function
PyObject *pyfun = PyObject_GetAttrString(pyModule, "main");
if(!pyfun || !PyCallable_Check(pyfun))
std::cout << "Cannot find python function" << std::endl;
return 0;
else
std::cout << "load python funtion ok" << "\\n";
//callback funtion
PyObject *argss = PyTuple_New(1);
PyObject *arg = PyString_FromString("127.0.0.1");
PyTuple_SetItem(argss, 0, arg);
PyObject *pyRes = PyObject_CallObject(pyfun, argss);
//get result
if(pyRes)
std::string ret = PyString_AsString(pyRes);
std::cout << "result: " << ret << "\\n";
Py_Finalize();
return 0;
其for_test.py的python代码如下:
import logging
import socket
import time
def main(ip):
proctime = time.strftime("%y%m%d_%H%M%S")
logging.basicConfig(level=logging.INFO, filename=proctime+'.log')
logging.info("Start program")
port = 8080
clientsocket_ = socket.create_connection((ip, port))
clientsocket_.send("for test")
logging.info("write file success")
logging.info("Ending program")
return "Test OK"
if __name__ == "__main__":
main("127.0.0.1") ## 运行前提为开启了服务器端
上面例子是传入一个参数并得到返回值的python函数调用,更多的调用方式可在网上找到大量相关资料。注意将for_test.py文件放到/home/user/test/下,否则会找不到相应python模块。
通过上述例子,便可以很方便地实现python调用。
不过,发现调用ros自身提供的python函数,比如rostopic中的get_topic_type("/rosout")函数,rosservice中的get_service_list()函数,这些函数都非常好用非常方便。只是通过上述方法总是调用不成功,会出现以下提示:
说“'module' object has no attribute 'argv'" in <module 'threading' from '/usr/lib/python2.7/threading.pyc'> ignored”。但即使删除了threading.pyc也还是不行,原因暂时不明,不知道是否有人已经解决。
以上是关于ROS工程中C++调用python函数的主要内容,如果未能解决你的问题,请参考以下文章