Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  3. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

NullReferenceException on ROSTCPConnector.RosTopicState.Deserialize

Discussion in 'Robotics' started by solidsnake530, Oct 26, 2021.

  1. solidsnake530

    solidsnake530

    Joined:
    Feb 9, 2017
    Posts:
    6
    Hey,

    I'm sure this will end up being a "me" problem ;)

    I'm using Unity Robotics with a Clearpath Husky. I am running ROS Kinetic (which I know is not supported, however the colour change demo does work).

    My problem comes when I'm trying to subscribe to the Husky msg "HuskyStatusMsg". I simply want text fields to display all the different parameters measured in this message (battery voltage, motor current, etc.). Basic code for fetching the battery voltage is as below.

    Code (CSharp):
    1. using UnityEngine;
    2. using Unity.Robotics.ROSTCPConnector;
    3. using RosHusky = RosMessageTypes.Husky.HuskyStatusMsg;
    4. using TMPro;
    5.  
    6. public class RosSubscriberExample : MonoBehaviour
    7. {
    8.     public TextMeshProUGUI TM_Battstate;
    9.  
    10.     void Start()
    11.     {
    12.         ROSConnection.GetOrCreateInstance().Subscribe<RosHusky>("huskystate", UpdateTelemetry);
    13.     }
    14.  
    15.     void UpdateTelemetry(RosHusky rosHusky)
    16.     {
    17.         TM_Battstate.text = rosHusky.ToString();
    18.     }
    19. }
    The Unity application successfully connects to ROS using ROS TCP Endpoint and ROS TCP Connector, which is great!

    However, on every update I get the following message


    NullReferenceException: Object reference not set to an instance of an object
    Unity.Robotics.ROSTCPConnector.RosTopicState.Deserialize (System.Byte[] data) (at Library/PackageCache/com.unity.robotics.ros-tcp-connector@7f055108f4/Runtime/TcpConnector/RosTopicState.cs:142)
    Unity.Robotics.ROSTCPConnector.RosTopicState.OnMessageReceived (System.Byte[] data) (at Library/PackageCache/com.unity.robotics.ros-tcp-connector@7f055108f4/Runtime/TcpConnector/RosTopicState.cs:87)
    Unity.Robotics.ROSTCPConnector.ROSConnection.Update () (at Library/PackageCache/com.unity.robotics.ros-tcp-connector@7f055108f4/Runtime/TcpConnector/ROSConnection.cs:586)


    Again, this does not happen when running the colour change demo. I am using the messages from this repository - https://github.com/husky/husky/tree/kinetic-devel.

    Would appreciate any advice as to what I'm doing wrong, I've not figured out what needs to go in the quotation marks inside the ROSConnection line so wondering if that's causing issues.
     
  2. HamidYounesy-Unity

    HamidYounesy-Unity

    Unity Technologies

    Joined:
    May 7, 2021
    Posts:
    3
    Is it possible that message has been registered under a different RosMessageName from the one subscribing to. Could you please check the RosMessageName for the HuskyMsg class (Should be "husky_msgs/HuskyStatus") and compare it with the one used in the function ("huskystate").
     
    solidsnake530 likes this.
  3. solidsnake530

    solidsnake530

    Joined:
    Feb 9, 2017
    Posts:
    6
    Thanks for getting back to me! I have changed it to "husky_msgs/HuskyStatus" as you are correct, however I'm still receiving the same error message unfortunately. Simply "HuskyStatus" has the same effect.
     
  4. LaurieUnity

    LaurieUnity

    Unity Technologies

    Joined:
    Oct 23, 2020
    Posts:
    77
    Hi, in the quotation marks in that ROSConnection line, you'll put the ros topic that you want to subscribe to. It needs to match the topic name the publisher is publishing on. (I'm guessing "huskystate" was the right topic, since your error shows you have actually received a message - you're just failing to read it).

    According to the call stack you pasted, something was null in RosTopicState line 142 - presumably m_Deserializer.

    Each message class we generate has a k_RosMessageName variable that defines its message name, and on startup it adds itself to the MessageRegistry under that name. Later, we call GetDeserializeFunction with the same string in order to find out how to deserialize messages of that type.

    If GetDeserializeFunction has returned null, the registry has never heard of the message name we're using - my guess is that somehow the RosTopicState's m_RosMessageName was different from the message class's k_RosMessageName.

    Could you put a breakpoint on in RosTopicState line 139 and find out what m_RosMessageName is, and whether it's the same as HuskyStatusMsg.k_RosMessageName?

    If you don't have a working debugger setup you could just print them instead:
    Code (CSharp):
    1. Debug.Log($"Getting {m_RosMessageName}, registered under {HuskyStatusMsg.k_RosMessageName}");
     
  5. solidsnake530

    solidsnake530

    Joined:
    Feb 9, 2017
    Posts:
    6
    Thanks for the further response!

    m_RosMessageName is: "tf/tfMessage"
    k_RosMessageName is: "husky_msgs/HuskyStatus"

    Line 64 of RosTopicState is thowing the error: "Inconsistent declaration of topic '/tf': was 'tf2_msgs/TFMessage', switching to 'tf/tfMessage'."

    So, I think your hypothesis is right. Question for me is why m_RosMessageName is tf/tfMessage.

    Just before I hit send on this I tried changing the TF Topics element of ROSConnectionPrefab from tf/tfMessage to husky_msgs/HuskyStatus which seems to have eliminated the NullReferenceException error, I'm still not getting any output (just trying to print the uptime to a string to test it) but this is presumably a configuration error on my part in ROS, as the breakpoints in my UpdateTelemetry function never trigger. (code has been updated as below)

    Code (CSharp):
    1. void UpdateTelemetry(RosHusky rosHusky)
    2.     {
    3.         TM_Uptime.text = rosHusky.uptime.ToString();
    4.         Debug.Log(rosHusky.uptime);
    5.     }
    On the ROS end, default_server_endpoint.py is showing a successful subscription to the topic so assume that's all good now too. I have to say I'm more of a Unity user than a ROS user at this point so still learning! But I think this particular issue has been squashed.
     
  6. LaurieUnity

    LaurieUnity

    Unity Technologies

    Joined:
    Oct 23, 2020
    Posts:
    77
    In ROS a lot of different components will regularly report their transform position & orientation on the /tf topic by default. This has nothing to do with the husky status messages.

    I think your test was messed up because ROSConnection automatically subscribes to the /tf topic, and your breakpoint caught it receiving one of those messages instead of a husky status message.

    You can turn off the subscription to /tf by selecting the ROSConnectionPrefab in your Assets/Resources folder, and untick "Listen for TF messages". (Awkward, I know; we'll be moving this to the Ros Settings window soon.)

    Once that's turned off, hopefully you can catch it receiving an actual husky status message.
     
    solidsnake530 likes this.