Search code examples
c#unity-game-engineros

Can't Subscribe to Nodes RosSharp C# Unity


I cannnot subscribe to any topics using RosSharp. I am working entirely locally-on the same machine. I am fairly certain I have the right uri with the right port and cannot get any communication. I am running ROS through Win-ROS: https://ros-win.visualstudio.com/_git/ros-win?path=%2Fdoc%2FSetup.md&version=GBmaster

On my local Windows host machine, I am running roscore and publishing a node with: rostopic pub -r 10 /testtopic std_msgs/String "whatever".

I'm able to run a subscriber from the command prompt with rostopic echo /testtopic and receive the correct data back, but I cannot get this subscriber to work in Unity. I'm expecting SubscriptionHandler to at least be called. This is the code I'm trying to replicate: https://github.com/siemens/ros-sharp/blob/a45e847f96d7dd1a7859dd9595e05ef27b27b5c3/Libraries/RosBridgeClientTest/RosSocketTests.cs

Below is my code attached to a GameObject, any help would be appreciated. Thank you.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using RosSharp.RosBridgeClient;
using std_msgs = RosSharp.RosBridgeClient.Messages.Standard;

public class BasicROS : MonoBehaviour {

    public string uri = "ws://18.40.26.172:11311";
    private RosSocket rosSocket;
    string subscriptionId = "";

    void Start () {
        rosSocket = new RosSocket(new 
        RosSharp.RosBridgeClient.Protocols.WebSocketNetProtocol(uri)); // 10.189.42.225:9090
        Subscribe("/testtopic");
    }

    public void Subscribe(string id)
    {
        subscriptionId  = rosSocket.Subscribe<std_msgs.String>(id, SubscriptionHandler);
        StartCoroutine(WaitForKey());     
    }

    private IEnumerator WaitForKey()
    {
        Debug.Log("Press any key to close...");

        while (!Input.anyKeyDown)
        {
            yield return null;
        }

        Debug.Log("Closed");
       // rosSocket.Close();
    }

    private void SubscriptionHandler(std_msgs.String message)
    {
        Debug.Log("Message received!");
        Debug.Log(message.data);
    }
}

Solution

  • At the time of this writing, ros-win doesn't support rosbridge, which is the ros-websocket bridge that rosSharp can communicate with. If you must use ros-win and use RosSharp to do websocket communication in unity, then you will need to wait or write your own port of rosbridge.

    If you can replace ros-win with ros on WSL, then you can do the following:

    Install the ros-websocket bridge suite. (Note: desktop-full does not include this, so be sure you actually get this package)

    sudo apt-get install ros-<rosdistro>-rosbridge-suite
    

    e.g.,

    sudo apt-get install ros-melodic-rosbridge-suite
    

    Run it with roslaunch rosbridge_server rosbridge_websocket.launch in order for web socket messages to reach the ros network.

    Doing that will create a websocket listener on port 9090, so you need to change your uri to use port 9090.

    Also, you may want to use localhost, i.e., uri = "ws://localhost:9090";, to avoid routing issues.