Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only.

    Please, do not make any changes to your username or email addresses at id.unity.com during this transition time.

    It's still possible to reply to existing private message conversations during the migration, but any new replies you post will be missing after the main migration is complete. We'll do our best to migrate these messages in a follow-up step.

    On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live.


    Read our full announcement for more information and let us know if you have any questions.

Unity to ROS publisher frequency drops when subscribed to a topic

Discussion in 'Robotics' started by seanminghanlim, Jul 22, 2021.

  1. seanminghanlim

    seanminghanlim

    Joined:
    Jan 23, 2021
    Posts:
    2
    Hi, I've got an issue that has me a bit stumped. I am trying to motor commands out to a robot from Unity to ROS at a fixed frequency of 100 Hz (I have the publish function within FixedUpdate()). When using rostopic hz /topic_name, I can see that the data is being published at 100 Hz with minute deviations. However, when I have this Unity publisher script subscribe to the pose data of the robot at the same time, the publishing frequency drops to 90 Hz (sometimes 70). All I'm doing within the script is a simple PID controller with the pose as input and motor commands as output, so I don't think the calculations are what's holding it up. Thoughts? Would greatly appreciate any help!
     
  2. LaurieUnity

    LaurieUnity

    Unity Technologies

    Joined:
    Oct 23, 2020
    Posts:
    77
    That's strange, ROSConnection sends and receives data on two separate threads, so in theory there shouldn't be any interference between the two. Would you be able to share your setup so we can test it?
     
  3. seanminghanlim

    seanminghanlim

    Joined:
    Jan 23, 2021
    Posts:
    2
    Thanks for the response! I have a pretty simple set up. it's just an instance of a publisher and a subscriber within the same monobehaviour script. I copied the server_endpoint from the robotics_demo package and made changes such that it is publishing and subscribing to a custom motor command message type and subscribed to a standard PoseStamped message type. I tested this again on a clean project and found that even the publisher side sometimes dips to 90 Hz when operating on its own. I didn't make any significant changes to the code found in the tutorials on GitHub except for putting the send command into FixedUpdate(). I've attached the changes I made to server_endpoint.py below.

    Code (Python):
    1.  
    2. #!/usr/bin/env python
    3.  
    4. import rospy
    5.  
    6. from ros_tcp_endpoint import TcpServer, RosPublisher, RosSubscriber, RosService, UnityService
    7. from crazyflie_driver.msg import Motor
    8. from geometry_msgs.msg import PoseStamped
    9.  
    10. def main():
    11.     ros_node_name = rospy.get_param("/TCP_NODE_NAME", 'TCPServer')
    12.     buffer_size = rospy.get_param("/TCP_BUFFER_SIZE", 1024)
    13.     connections = rospy.get_param("/TCP_CONNECTIONS", 10)
    14.     tcp_server = TcpServer(ros_node_name, buffer_size, connections)
    15.     rospy.init_node(ros_node_name, anonymous=True)
    16.  
    17.     tcp_server.start({
    18.         'cmd_motor': RosPublisher('cmd_motor', Motor, queue_size=10),
    19.         'pose': RosSubscriber('pose', PoseStamped, tcp_server),
    20.     })
    21.  
    22.     rospy.spin()
    23.  
    24.  
    25. if __name__ == "__main__":
    26.     main()
     
  4. mrpropellers

    mrpropellers

    Unity Technologies

    Joined:
    Jul 10, 2019
    Posts:
    13
    There are a number of different points along the pipeline that could be slowing you down. Note that, in ROS, a publisher effectively can only publish its next message once every subscriber has finished receiving the previous message. With multiple subscribers, the publisher is responsible for sending a duplicate of its data to every subscriber in its list, and waiting for them all to finish receiving the message before it can publish the next in its queue. I'm not sure if this is done in a threaded manner without doing a deep dive into ROS's implementation, but my suspicion would be 1 thread per publisher, or it is spinning up/down pooled threads for each publish. Either way, there's going to be an additive effect on the amount of time it takes between each publish call for each subscriber on that topic (
    rostopic hz
    counts as a subscriber). If you're trying to publish at 100hz, you only have 10ms between each publish attempt for all network stream reads and deserializations to complete before your publisher will start to slow down and drop messages.

    Some things to investigate would be:
    1. How much work did you move into FixedUpdate? It's only guaranteed to run at the defined update speed if the previous FixedUpdate completes before the next is scheduled to start.
    2. Is there a 1:1 relationship between pose inputs and motor outputs? If you're blocking waiting for a pose input, your publishing rate can only be as fast as the slower component (incoming messages are deserialized during
    Update
    inside Unity).
    3. What window size are you using (
    -w
    ) for
    rostopic hz
    ? Network hiccups or nodes going down/up again can affect your frequency measurement if your window is large.