You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Webots中实现Matlab控制器与Supervisor间的数据传递?

机器人控制器向Supervisor传递布尔值的Matlab通信问题

我需要在Matlab环境下实现:机器人控制器检测到物体时,向Supervisor发送布尔值。尝试过TCP/IP和全局变量两种方案,均未成功。

控制器代码(原实现)

data_to_send = false;
client_socket = tcpip('localhost', 12345);
fopen(client_socket);
while true
    fwrite(client_socket, data_to_send, 'boolean');
end
fclose(client_socket);

Supervisor代码(原实现)

server_socket = tcpip('0.0.0.0', 12345, 'NetworkRole', 'server');
fopen(server_socket);
while true
    while ~server_socket.BytesAvailable
        pause(0.1);
    end
    received_data = fread(server_socket, server_socket.BytesAvailable, 'boolean');
    disp(['Received data from the controller: ', num2str(received_data)]);
end
fclose(server_socket);

问题分析与修复方案

原代码核心问题

  1. 控制器端无限循环无退出逻辑:while true会持续发送false,且永远执行不到fclose,导致连接无法正常关闭,还会占用大量资源。
  2. 无错误处理机制:两端都未处理连接中断、端口占用等异常,出现问题会直接崩溃。
  3. Supervisor接收逻辑冗余:每次读取所有可用字节,布尔值仅占1字节,重复读取易导致数据堆积。

修复后的控制器代码(加入检测逻辑与合理通信流程)

% 初始化TCP客户端
client_socket = tcpip('localhost', 12345);
fopen(client_socket);

try
    while true
        % 替换为实际的物体检测代码,返回true/false
        object_detected = false; 
        
        % 发送布尔值
        fwrite(client_socket, object_detected, 'boolean');
        pause(0.1); % 控制发送频率,避免资源浪费
        
        % 按ESC键退出循环(可选)
        if ~isempty(get(gcf,'CurrentCharacter')) && get(gcf,'CurrentCharacter') == char(27)
            break;
        end
    end
catch ME
    disp(['通信错误: ', ME.message]);
end

% 关闭并清理连接
fclose(client_socket);
delete(client_socket);
clear client_socket;

修复后的Supervisor代码(优化接收与错误处理)

% 初始化TCP服务器
server_socket = tcpip('0.0.0.0', 12345, 'NetworkRole', 'server');
fopen(server_socket);

try
    while true
        if server_socket.BytesAvailable >= 1 % 布尔值占1字节,满足条件再读取
            received_data = fread(server_socket, 1, 'boolean');
            disp(['收到控制器数据: ', num2str(received_data)]);
        end
        pause(0.05); % 降低轮询频率,减少CPU占用
    end
catch ME
    disp(['通信错误: ', ME.message]);
end

% 关闭并清理连接
fclose(server_socket);
delete(server_socket);
clear server_socket;

额外注意事项

  • 运行顺序:必须先启动Supervisor端代码,再启动控制器端,确保服务器先监听端口。
  • 全局变量方案补充:Matlab跨脚本全局变量需两端都声明global var_name,且需通过evalin/assignin跨工作区访问,稳定性远不如TCP/IP。
  • 替代方案:如果TCP/IP仍有问题,可尝试Matlab的udp通信,或使用sharedmemory工具箱实现进程间内存共享。

内容的提问来源于stack exchange,提问作者Matsuyama Kinji

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 16:42:25