Xamla / ROS.NET

ROS .NET Core Client Library
http://robotics.cs.uml.edu/
BSD 2-Clause "Simplified" License
16 stars 11 forks source link

Running two Publishers in same thread does not work #10

Open antoabbot opened 4 years ago

antoabbot commented 4 years ago

Hi

I am attempting to run two publishers in the same thread. I can get either to run fine and publish messages to my robot (one is a camera Pan/Tilt and one is a velocity command). However when both are instantiated, neither run, and sometimes (I believe) I have had one or the other intermittently running. The firing frequency is high for the Velocity message as it will timeout on the bot

My sample code is attached and the behaviour can be triggered via command line arguments. Please advise how to run multiple publishers in an application? In my real micro service, each Publish is triggered by some incoming signalR requests, but I get the same behaviour

It seems that even the instantiation of the Publisher via Node.Advertise<>() causes the issue

using System;
using Uml.Robotics.Ros;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Globalization;

namespace ROSTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var localIp = GetLocalIPAddress();

            // Pass a commandline and work out what to run
            // C will run the camera, V the motors , and CV both
            var runCam = (args.Length == 1 && args[0].Contains('c', StringComparison.InvariantCultureIgnoreCase));
            var runVel = (args.Length == 1 && args[0].Contains('v', StringComparison.InvariantCultureIgnoreCase));

            // Global ROS initialisation
            if (string.IsNullOrEmpty(ROS.ROS_MASTER_URI))
                ROS.ROS_MASTER_URI = "http://192.168.8.141:11311";

            ROS.ROS_HOSTNAME = localIp;
            ROS.Init(new string[0], "XoXoTest" + DateTime.UtcNow.Ticks.ToString());
            var spinner = new SingleThreadSpinner();
            var node = new NodeHandle();

            // Predeclare the publishers and set to null.
            Publisher<Messages.geoff_msgs.GeoffPanTilt> cameraPublisher = null;
            Publisher<Messages.geometry_msgs.Twist> velPublisher = null;

            // Only instantiate if needed. This is to test the behaviour of two Publishers in the same thread
            if (runCam)
            {
                cameraPublisher = node.Advertise<Messages.geoff_msgs.GeoffPanTilt>("/pan_tilt", 1000);
                Console.WriteLine("Runnning Camera");
            }

            // Only instantiate if needed. This is to test the behaviour of two Publishers in the same thread
            if (runVel)
            {
                velPublisher = node.Advertise<Messages.geometry_msgs.Twist>("/cmd_vel", 1000);
                Console.WriteLine("Runnning Motors");
            }

            var dt = 50; // Time delay for the message loop in milliseconds
            uint i = 0;

            unchecked // To allow the int to overflow if it reaches the end
            {
                while (ROS.OK && !Console.KeyAvailable)
                {
                    // Generate some sinusoidal inputs
                    var pan = (short)(Math.Sin(i / (0.5 * dt)) * 32767);
                    var tilt = (short)(Math.Cos(i / (0.3 * dt)) * 32767);
                    var vel = Math.Sin(i / (1.0 * dt));
                    var twist = Math.Cos(i / (0.7 * dt));

                    if (velPublisher != null)
                    {
                        var vmsg = new Messages.geometry_msgs.Twist();
                        vmsg.linear.x = vel;
                        vmsg.angular.z = twist;
                        velPublisher.Publish(vmsg);
                        spinner.SpinOnce();
                    }

                    if (cameraPublisher != null)
                    {
                        var msg = new Messages.geoff_msgs.GeoffPanTilt { pan = pan, tilt = tilt };
                        cameraPublisher.Publish(msg);
                        spinner.SpinOnce();
                    }

                    Thread.Sleep(dt);
                    i++;
                }
            }

            ROS.Shutdown();
            Console.WriteLine("Done");
        }

        private static string GetLocalIPAddress()
        {
            string localIP;
            using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
            {
                socket.Connect("8.8.8.8", 65530);
                IPEndPoint endPoint = socket.LocalEndPoint as IPEndPoint;
                localIP = endPoint.Address.ToString();
            }

            return localIP;
        }
    }
}
antoabbot commented 4 years ago

Update: This problem happens when the .NET code above runs on a different machine (Mac OS) to the Master (Ubuntu on Nvidia Jetson). When I run the .NET code on the Jetson, then the Publishers work concurrently as designed.

andreaskoepf commented 4 years ago

Your code should generally work. Does a single publisher work with the ROS master running on a different machine (e.g. only the GeoffPanTilt and the Twist separately)? Are both topics visible on the master machine when you type rostopic list? Is the geoff_msgs definition compiled on the machine that runs the Master?

antoabbot commented 4 years ago

Yes yes and yes. The final usage is with it all on one machine and it runs perfectly with both publishers in this case. So I’m not too bothered except for when I’m debugging and developing from visual studio off the bot.

Get Outlook for iOShttps://aka.ms/o0ukef


From: Andreas Köpf notifications@github.com Sent: Tuesday, June 30, 2020 11:53:12 AM To: Xamla/ROS.NET ROS.NET@noreply.github.com Cc: antoabbot ahabbot@gmail.com; Author author@noreply.github.com Subject: Re: [Xamla/ROS.NET] Running two Publishers in same thread does not work (#10)

Your code should generally work. Does a single publisher work with the ROS master running on a different machine (e.g. only the GeoffPanTilt and the Twist separately)? Are both topics visible on the master machine when you type rostopic list? Is the geoff_msgs definition compiled on the machine that runs the Master?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/Xamla/ROS.NET/issues/10#issuecomment-651689971, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AD2OCJPSV3APWAJDRATKNM3RZGYYRANCNFSM4OLRSS6Q.