Docker 環境での ROS 2 に特有のノード検出タイミングに関する問題と考えられます。 DDS 層において、ノードのメタデータが完全に伝播する前にトピックが先に検出されてしまい、その結果としてサブスクライバが正しく動作しないことがあります。以下の手順を参考に、MATLABとdockerのROS 2 環境を統一することで改善できる可能性があります。
ROS 2 を実行している環境(Docker)と、MATLAB を実行しているマシンとの通信が可能であることを確認します。
# In Docker
# On host
On MATLAB (Ubuntu host):
clear all;
fprintf('Current ROS_DOMAIN_ID: %s\n', getenv('ROS_DOMAIN_ID'));
fprintf('Current RMW_IMPLEMENTATION: %s\n', getenv('RMW_IMPLEMENTATION'));
On Docker container:
# Stop all ROS 2 processes
pkill -9 ros2
ros2 daemon stop
sleep 2
# Verify current settings
echo "ROS_DOMAIN_ID: $ROS_DOMAIN_ID"
echo "RMW_IMPLEMENTATION: $RMW_IMPLEMENTATION"
echo "ROS_LOCALHOST_ONLY: $ROS_LOCALHOST_ONLY"
On MATLAB:
setenv('ROS_DOMAIN_ID', '4');
setenv('RMW_IMPLEMENTATION', 'rmw_cyclonedds_cpp');
setenv('ROS_LOCALHOST_ONLY', '0');
fprintf('Domain ID set to: %s\n', getenv('ROS_DOMAIN_ID'));
fprintf('RMW set to: %s\n', getenv('RMW_IMPLEMENTATION'));
On Docker:
export ROS_DOMAIN_ID=4
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
export ROS_LOCALHOST_ONLY=0
Test A: Publish from MATLAB → Subscribe in Docker
testNode = ros2node('matlab_test_node');
testPub = ros2publisher(testNode, '/test_topic', 'std_msgs/String');
testMsg = ros2message(testPub);
testMsg.data = 'Hello from MATLAB';
for i = 1:20
testMsg.data = sprintf('Message %d from MATLAB', i);
send(testPub, testMsg);
fprintf('Sent: %s\n', testMsg.data);
pause(1);
end
On Docker:
# First, verify topic is visible
ros2 topic list | grep test_topic
# Check topic info (important!)
ros2 topic info /test_topic -v
# Wait until you see the node name appear (not _NODE_NAME_UNKNOWN_)
# Then subscribe
ros2 topic echo /test_topic
Test B: Publish from Docker → Subscribe in MATLAB
※テストAと逆方向の通信も確認してください