Unity-Robotics-Hub
Unity-Robotics-Hub copied to clipboard
RosPublisherExample gives warning in ROS2 Humble
Description of the bug
Publishing the example PosRot message from the unity_robotics_demo_msgs package using ROS2 gives warning log.
To Reproduce
Steps to reproduce the behavior:
- Run up ros_tcp_endpoint version 0.7 and launch with default config e.g.
ROS_IP=0.0.0.0port 10000. - Start the RosPublisherExample in a Unity project.
Console logs
root@78932a399808:/ros2_ws# ros2 run ros_tcp_endpoint default_server_endpoint --ros-args -p ROS_IP:=0.0.0.0
[INFO] [1655364893.499026344] [UnityEndpoint]: Starting server on 0.0.0.0:10000
[INFO] [1655364914.368200902] [UnityEndpoint]: Connection from 172.19.0.1
[INFO] [1655364914.540648798] [UnityEndpoint]: RegisterSubscriber(/tf, <class 'tf2_msgs.msg._tf_message.TFMessage'>) OK
[INFO] [1655364914.547903045] [UnityEndpoint]: RegisterPublisher(pos_rot, <class 'unity_robotics_demo_msgs.msg._pos_rot.PosRot'>) OK
[WARN] [1655364914.548093382] [rcl.logging_rosout]: Publisher already registered for provided node name. If this is due to multiple nodes with the same name then all logs for that logger name will go out over the existing publisher. As soon as any node with that name is destructed it will unregister the publisher, preventing any further logs for that name from being published on the rosout topic.
[INFO] [1655364914.552324273] [UnityEndpoint]: RegisterPublisher(pos_rot, <class 'unity_robotics_demo_msgs.msg._pos_rot.PosRot'>) OK
Expected behavior
A clear and concise description of what you expected to happen.
A single INFO RegisterPublisher log without a warning.
Screenshot

Environment
- Unity Version: Unity 2020.3.19f1
- Unity machine OS + version: Windows 11
- ROS machine OS + version: Ubuntu 20.04, ROS2 Humble
- ROS–Unity communication: Docker
- Branch or version: v0.7.0
I have the same problem, too. My environment is a bit different.
- Unity Version: Unity 2021.3.4f1
- Unity machine OS: Windows 11
- ROS machine OS: Ubuntu 20.04 on WSL2
- ROS Version: ROS2 Galactic
- ROS-Unity communication: over WSL2
- ROS TCP Connector Version: v0.7.0
I tried to find out the reason by tracing the process of registering a publisher, and I've found that public RosTopicState RegisterPublisher(...) in ROSConnection.cs calls topicState.RegisterPublisher(resolvedQueueSize, resolvedLatch) at line 352 and it stores a command of registering a publisher in the queue, although public RosTopicState RegisterPublisher(...) calls GetOrCreateTopic(rosTopicName, rosMessageName) at line 348 and it also stores a command registering a publisher in the same queue when a connection with ROS TCP Endpoint is established.
The commands stored in the queue will be sent after the connection with ROS TCP Endpoint is ready, and that means the current implementation does try to register the same publisher twice. I don't know why the current ROS TCP Connector is implemented in this way.
I don't think this is a good idea but commenting out either line 207 or 260 of RosTopicState.cs can make the warning in question disappear.
(commenting out line 207)
public void RegisterPublisher(int queueSize, bool latch)
{
if (IsPublisher)
{
Debug.LogWarning($"Publisher for topic {m_Topic} registered twice!");
return;
}
IsPublisher = true;
IsPublisherLatched = latch;
// m_ConnectionInternal.SendPublisherRegistration(m_Topic, m_RosMessageName, queueSize, latch); // comment out
CreateMessageSender(queueSize);
}
(or commenting out line 260)
internal void OnConnectionEstablished(NetworkStream stream)
{
if (m_SubscriberCallbacks.Count > 0 && !SentSubscriberRegistration)
{
m_ConnectionInternal.SendSubscriberRegistration(m_Topic, m_RosMessageName, stream);
SentSubscriberRegistration = true;
}
if (IsUnityService)
{
m_ConnectionInternal.SendUnityServiceRegistration(m_Topic, m_RosMessageName, stream);
}
if (IsPublisher)
{
//Register the publisher before sending anything.
//m_ConnectionInternal.SendPublisherRegistration(m_Topic, m_RosMessageName, m_MessageSender.QueueSize, IsPublisherLatched, stream); // comment out
if (IsPublisherLatched)
{
m_MessageSender.PrepareLatchMessage();
m_ConnectionInternal.AddSenderToQueue(m_MessageSender);
}
}
if (m_IsRosService)
{
m_ConnectionInternal.SendRosServiceRegistration(m_Topic, m_RosMessageName, stream);
}
}