ROS-TCP-Connector icon indicating copy to clipboard operation
ROS-TCP-Connector copied to clipboard

GetTopic doesn't work unless a topic exists at launch.

Open JustinKovacich opened this issue 3 years ago • 0 comments

Describe the bug Hi. I probably have a more complicated workflow vs. what you guys normally deal with, but I have an application that allows ROS as a possible input, but not a required input. As such, I don't necessarily have any ROS topics running on startup, or the topics I'm interested in, running when the application launches. I have found if I don't have the topics I'm interested in subscribing to running when the application launches, GetTopic (and the underlying m_topics list) do not have the topics I want in them.

Right now I am relying on a callback from GetTopicAndTypeList, which does return the up to date list, to set everything and subscribe. I had tried to do things like check the SentSubscriberRegistration and others for some state-related info, but I don't appear to be able to get that to work unless its there on startup.

To Reproduce This is the gist of my setup: ///

/// The topic list buffer. /// private Dictionary<string, string> topicList = new Dictionary<string, string>();

    public List<string> subscribedTopics;
    
    /// <summary>
    /// Dictionary of topic names and their types encoded as strings.
    /// </summary>
    public Dictionary<string, string> TopicListDictionary
    {
        get => topicList;
        set
        {
            if ( topicList == value )
            {
                return;
            }

            topicList = value;
            foreach (topic in topicList)
           {

               if (!subscribedTopics.Contains(topic.Key))
               {
                    subscribedTopics.Add(topic.Key);
                    if ( ROSConnectionInstance.GetTopic( topic.Key ).SentSubscriberRegistration )
                    {
                        continue;
                    }

                    ROSConnectionInstance.Subscribe<RosMessageTypes.Sensor.PointCloud2Msg>(topic.Key, TransferPcl2Points);
               }
           }
        }
    }
    
    private void Update()
    {
            // I use some timer here to limit this but for the example this works
            PerformRosUpdate();
    }

    /// <summary>
    /// Performs the update of ROS connection status and topics.
    /// </summary>
    /// <returns></returns>
    private void PerformRosUpdate()
    {
        if ( !ROSConnection.GetOrCreateInstance().HasConnectionError )
        {
            ROSConnection.GetOrCreateInstance().GetTopicAndTypeList( CopyTypesToList );
        }
    }

    private void TransferPcl2Points(RosMessageTypes.Sensor.PointCloud2Msg pcl2Points)
    {
        //unrelated;
    }
    
    /// <summary>
    /// A callback to copy the topic list with their types from ROS to here.
    /// </summary>
    private void CopyTypesToList( Dictionary<string, string> topicsAndTypes )
    {
        TopicListDictionary = topicsAndTypes;
    }

Console logs / stack traces Please wrap in triple backticks (```) to make it easier to read.

Expected behavior If the topic exists before I've run my application, the above works great. If it doesn't, the application crashes because if ( ROSConnectionInstance.GetTopic( topic.Key ) returns NULL.

Screenshots If applicable, add screenshots or videos to help explain your problem.

Environment (please complete the following information, where applicable):

  • Unity Version: [e.g. Unity 2020.3.21f1]
  • Unity machine OS + version: [e.g. Ubuntu 18.04]
  • ROS machine OS + version: [e.g. Ubuntu 18.04, ROS Melodic]
  • ROS–Unity communication: [Same machine]
  • Branch or version: ROS-TCP-Endpoint-0.7.0

JustinKovacich avatar Jun 17 '22 20:06 JustinKovacich