如何让Webots支持C#语言开发的控制器

Webots支持C、C++、Java、Python、Matlab这五种语言开发控制器,没有直接支持C#,但有个同事已经用C#写了大量的机器人控制代码,想在不把C#代码改写成C++的情况下,直接用webots仿真,那就得想想办法。(不过,让ChatGPT帮忙把一种语言的代码转成另外一种语言的代码,还是挺方便的,准确率很高。)

在Webots的安装路径下,找到lib\controller文件夹,里面有Controller.dll和Controller.lib文件,对于C#,我们只需要Controller.dll文件(C和C++的开发就需要Controller.lib文件),把这个dll文件复制到C#程序编译输出exe的文件夹里,通常是bin\x64\Debug\net8.0,(注意是跟输出的exe文件放在同一文件夹里,而不是跟C#的源代码放在同一文件夹里。既不需要,也不能在VS解决方案中添加对Controller.dll的引用,尝试添加它会报错。Controller.dll是64位的,所以C#程序也要编译成64位的。)

Controller.dll实现了(或者说导出了)Webots\include\controller\c\webots文件夹中所有的头文件中声明的全部函数(共932个),比如最常用wb_robot_init(), wb_robot_step(),wb_motor_set_position(), wb_motor_set_velocity(), wb_motor_get_target_position(),肯定都有的。而cpp的函数其实都是在调用c的函数,看看\Webots\src\controller\cpp里面的cpp文件就明白了。如果你装了VS 2022,可以打开开始菜单中Visual Studio 2022文件夹里的随便点开一个 xxx Command Prompt for VS 2022, 输入

bash 复制代码
dumpbin /exports "E:\Program Files\Webots\lib\controller\Controller.dll"

就能看到所有的导出函数了。

为了能使用Controller.dll,在C#的cs文件中,

cs 复制代码
using System.Runtime.InteropServices;

再去robot.h, motor.h等头文件中找你需要的函数的定义,然后在一个C#的class里面加入大量类似下面的语句

cs 复制代码
[DllImport("Controller.dll")]
public static extern void wb_robot_init();

看.h文件中的函数定义,一定会遇到WbDeviceTag,可以在Webots\include\controller\c\webots\types.h中找到对WbDeviceTag的定义:

cpp 复制代码
typedef unsigned short WbDeviceTag;

对应到C#中就是ushort类型。遇到const char *,就换成string. 把需要用到的函数都经过上面的声明后,就能和在C语言中一样使用这些函数了。示例C#代码如下:

cs 复制代码
using System.Runtime.InteropServices;

public class Program
{
    [DllImport("Controller.dll")]
    public static extern void wb_robot_init();

    [DllImport("Controller.dll")]
    public static extern void wb_robot_cleanup();

    [DllImport("Controller.dll")]
    public static extern void wb_robot_step(int duration);

    [DllImport("Controller.dll")]
    public static extern void wb_motor_set_position(ushort tag, double position);

    [DllImport("Controller.dll")]
    public static extern void wb_motor_set_velocity(ushort tag, double velocity);

    [DllImport("Controller.dll")]
    public static extern void wb_motor_get_target_position(ushort tag);

    [DllImport("Controller.dll")]
    public static extern ushort wb_robot_get_device(string name);

    public static void GetAllMotor(ref ushort[] motor)
    {       
        motor[10] = wb_robot_get_device("TA_joint_01");
        motor[9] = wb_robot_get_device("TA_joint_02");
        motor[8] = wb_robot_get_device("TA_joint_03");
        motor[7] = wb_robot_get_device("TA_joint_04");
        motor[6] = wb_robot_get_device("TA_joint_05");
    }

    public static void Main()
    {   wb_robot_init();
        ushort[] motor = new ushort[11];
        GetAllMotor(ref motor);
        wb_motor_set_position(motor[10], Math.PI/2); 
        wb_motor_set_position(motor[8], 3);   // 单位是弧度 
        wb_robot_step(500);
        wb_robot_cleanup();
        Console.ReadKey();
    }
}

启动C#程序后会看到如下报错,暂未发现有什么不良影响,还是能正常操作webots中的机器人。

Error: 找不到指定的模块。

(dynamic library)

Error: failed to load E:/Program Files/Webots/resources/projects/plugins/robot_windows/generic/generic.dll library.

generic.dll的路径是正确的,然而即使把generic.dll跟Controller.dll放在一起,也无法解决这个报错。

相关推荐
赏金术士几秒前
Kotlin 从入门到进阶 之基础语法模块(一)
开发语言·微信·kotlin
格林威几秒前
Baumer工业相机堡盟相机Chunk功能全解析:如何在图像中嵌入时间戳、编码器值等元数据?
开发语言·人工智能·数码相机·机器学习·计算机视觉·视觉检测·机器视觉
南宫萧幕2 分钟前
锂电池二阶 RC 模型仿真实战:从理论解析到 Simulink 闭环搭建全流程
开发语言·人工智能·算法·机器学习
Hical_W2 分钟前
Hical 踩坑实录五部曲(一):Boost.Asio 协程开发的 N 个坑
网络·c++·开源
水木流年追梦2 分钟前
【python因果库实战29】LaLonde 数据集2
开发语言·python·数据挖掘·langchain·机器人
不会编程的懒洋洋3 分钟前
WPF 性能优化+异步+渲染
开发语言·笔记·性能优化·c#·wpf·图形渲染·线程
春夜喜雨3 分钟前
类型定义的使用差异using/typedef/define/constexpr
c++·typedef·using·constexpr·类型定义·define·常量声明
故事和你913 分钟前
洛谷-数据结构2-1-二叉堆与树状数组2
开发语言·javascript·数据结构·算法·ecmascript·动态规划·图论
赏金术士3 分钟前
Kotlin 从入门到进阶 之面向对象 OOP 模块(三)
开发语言·网络·kotlin
智者知已应修善业6 分钟前
【51单片机流水灯中断嵌套,低优先级中断完成后如何返回主程序】2023-10-15
c++·经验分享·笔记·算法·51单片机