简体   繁体   English

SWIG 将 C++ 包装成 Python

[英]SWIG Wrap C++ into Python

I wrote a C++ module to compute the forward and inverse kinematics for my SCARA robot arm, and I want to wrap this module into Python so that I can use it in another application.我写了一个 C++ 模块来计算我的 SCARA 机器人 arm 的正向和反向运动学,我想将此模块包装到 ZA7F5F35426B927411FC9231B5638217Z 中,以便在另一个应用程序中使用它。 For the conversion, I chose SWIG, but it is pretty hard to write the interface file correctly.对于转换,我选择了 SWIG,但是很难正确编写接口文件。

In my header of C++ module, I have在我的 C++ 模块的 header 中,我有

namespace ARM_KINEMATICS{
    /*
       Forward kinematics
       [in] const double *q: joints' value
       [out] double *T: placeholder to put homogeneous transformation matrix, with length 16
     */
    void forward(const double *q, double *T);
    /*
       Inverse kinematics
       [in] const double *T: target homogenous transformation matrix with length 16
       [out] double q_sols: placeholder for solutions, with length 2*4
       [out] int: number of solutions
     */
    int inverse(const double *T, double *q_sols);
}

The expected behavior in Python would be like Python 中的预期行为就像

> import arm_kinematics
> T = [0.0] * 16
> arm_kinematics.forward([0.0, 0.0, 0.0, 0.0], T)
> T
  [1.0, 0.0, 0.0, 0.6, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.139, 0.0, 0.0, 0.0, 1.0]
> q_sols = [0.0] * 8
> num_sols = arm_kinematics.inverse(T, q_sols)
> q_sols[:num_sols*4]
  [0.0, 0.0, 0.0, 0.0]

How can I write the interface file so that it can convert Python list into C++ array and vice verse?如何编写接口文件,以便将 Python 列表转换为 C++ 数组,反之亦然? And is it possible to make Python pass by reference ?是否可以通过引用使 Python 通过 I found我发现

typemap类型图

can handle functions with known array size, for example int foo(int arr[4]) , but if now the array is passed by the pointer and we don't know its size, how should I revise the interface file?可以处理已知数组大小的函数,例如int foo(int arr[4]) ,但是如果现在数组是通过指针传递的,我们不知道它的大小,我应该如何修改接口文件?

Thank in advance!预先感谢!

The easiest way using SWIG is to use numpy.i使用 SWIG 的最简单方法是使用numpy.i

Change your C++ interface to this将您的 C++ 接口更改为此

namespace ARM_KINEMATICS{
  /*
    Forward kinematics
    [in] const double *q: joints' value
    [out] double *T: placeholder to put homogeneous transformation matrix, with length 16
  */
  void forward(const double *q, const int nq, double **T, int* nT);
  /*
    Inverse kinematics
    [in] const double *T: target homogenous transformation matrix with length 16
    [out] double q_sols: placeholder for solutions, with length 2*4
    [out] int: number of solutions
  */
  int inverse(const double *T, const int nT, double **q_sols, int* nq_sols);
}

A working interface for SWIG is then然后是 SWIG 的工作界面

%module robot
%{
  #define SWIG_FILE_WITH_INIT
  #include "robot.h"
%}

%include "numpy.i"

%init
%{
  import_array();
%}

%apply (double* IN_ARRAY1, int DIM1) {(const double *q, const int nq)}

%apply (double* IN_ARRAY1, int DIM1) {(const double *T, const int nT)}

%apply (double** ARGOUTVIEWM_ARRAY1, int* DIM1) \
{(double** T, int* nT)}

%apply (double** ARGOUTVIEWM_ARRAY1, int* DIM1) \
{(double** q_sols, int* nq_sols)}


%include "robot.h"

If you look into numpy.i , you will see that you can input/output matrices as well.如果您查看numpy.i ,您会发现您也可以输入/输出矩阵。

The typemaps are defined in numpy.i , which is shipped together with NumPy类型映射在numpy.i中定义,与 NumPy 一起提供

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM