xCore-SDK  0.5.0
xCore SDK C# API
C# 接口封装说明

C::封装用的是C++/CLI,是用来代替C++托管扩展(Managed C++,下文使用MC++指代)的语言。

新增接口和数据结构

和C++类似,在.hpp文件中写函数声明,在.cpp中实现

  • 定义在 BaseRobot类,Model类下面的函数, 在 robot_cli.hpp BaseRobot 类下面新增函数声明,在robot_cli.cpp写函数实现
  • 定义在 Robot_T, Model_T (也就是区分轴数的模板类) 下面的,也在 BaseRobot 类下面新增函数声明,实现时注意判断实际构造的机型,分别用 ir3 ir4 ir6 cobot5 cobot6 cobot7 调用C++函数
  • 定义在 BaseCobot 下面的,在 robot_cli.hpp Cobot类下面新增函数
  • 定义在 Cobot 类下面的, 也在Cobot类下面新增。同样地,注意判断实际构造的机型。
  • 少数和机型类别绑定的功能,比如setAvoidSingularity(), 只适用于六轴机型,那么在对应的类下面定义
  • 新增加的枚举类、数据结构,在data_types_cli.hpp 定义,写必要的构造函数
  • 力控指令类,在 force_control_cli新增
  • 如果有新增加的class, 可仿照 ForceControl

函数实现

简单来讲,每个封装函数完成3件事情:

  1. 转换传入的参数,从C::的数据类型转成C++的
  2. 通过raw pointer调用C++函数
  3. 转换传出的参数
int BaseRobot::checkPath(array<double>^ start_joint, array<CartesianPosition^>^ targets, array<double>^% target_joint_calculated, ErrorCode^% ec)
{
error_code _ec;
std::vector<double> _start_joint = convertArrayToVector(start_joint);
std::vector<double> _target_joint_calculated;
std::vector<rokae::CartesianPosition> _targets;
for each (CartesianPosition^ target in targets)
{
_targets.emplace_back(convertCartesianPosition(target));
}
auto ret = robot->checkPath(_start_joint, _targets, _target_joint_calculated, _ec);
convertErrorCode(_ec, ec);
target_joint_calculated = convertVectorToArray(_target_joint_calculated);
return ret;
}

以checkPath函数为例,start_joint 和 targets是传入参数,分别转换成C++中的 std::vector<double> , std::vector<CartesianPosition>

然后调用原始C++函数。

target_joint_calculated 和 ec是传出的参数,分别转换成array<double>^ 和自定义的 ErrorCode

converter_cli.hpp中写了一些常用的转换函数

数据类型对应关系

基础数据类型

C++数据类型 C++/CLI数据类型 转换说明
int, double, float,bool 不需要转换
uint8_t, unsigned char Byte 不需要转换
int8_t, char SByte 不需要转换
std::string System.String^ 见convertString()
std::vector<T>, std::array<T> array<T>^ 遍历数组,逐个元素转换

注: 早期部分vector转换成了List, 不再建议使用

自定义数据类型

基本上,自定义的数据类型都定义为引用类型(ref class)。参数类型后面带的 ^ 符号就代表这是一个引用类型。转换方式参考converter_cli.cpp

传入和传出参数

传入参数无需特殊声明。传出参数有两种标注方式:

  1. 在参数类型后面加 %, 比如上方示例里的 array<double>^% target_joint_calculated
  2. 在参数类型前面加 [Out] 标志,同时加 %, 比如所有的错误码 [Out] ErrorCode^% ec。和上一种的区别是函数实现里要负责创建该参数的对象。比如,每个函数里都会执行这样一行
ec = gcnew ErrorCode(_ec.value(), gcnew System::String(_ec.message().data()));

gcnew 就是用于分配内存并创建对象

一般使用第一种方式标注就行

模板函数

C::中的泛函数和C++中的概念不太一样,所以模板函数要把支持的参数类型都声明定义一遍。参考 writeRegister

函数注释

每个函数都要在.hpp写函数注释,仿照已有的写就行