Unity-Technologies / ROS-TCP-Connector

Apache License 2.0
287 stars 90 forks source link

Weird behavour when publishing ClockMsg at high frequency #275

Closed mojervico closed 1 year ago

mojervico commented 2 years ago

Hi

I'm trying to publish a message of time RosMessageTypes.Rosgraph.ClockMsg every fixed time step in the simulation (time_step=0.01). However, when i print the topic in the terminal a see a weird behavior. image

it is sending some time future time stamps, that the simulator hasn't arrived yet. Since I print the values in the unity terminal and the displays values are correct

NotwithStanding, if I use a bigger type of message, i.e RosMessageTypes.Sensor.JointStateMsg and embedded the clock message there. I got nice results. When I tried with message types like HeaderMsg it also present a weird behaviour.

Here is my code

public class ClockSimulation : MonoBehaviour
{
    // Start is called before the first frame update
    Unity.Robotics.ROSTCPConnector.ROSConnection ros;
    public string clock_topic="clock";
    public string clock_real_topic="clock_real";
    void Start()
    {
        ros = Unity.Robotics.ROSTCPConnector.ROSConnection.GetOrCreateInstance();
        ros.RegisterPublisher<RosMessageTypes.Sensor.JointStateMsg>(clock_topic);
        ros.RegisterPublisher<RosMessageTypes.Rosgraph.ClockMsg>(clock_real_topic);
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        var sensor_msg= new RosMessageTypes.Sensor.JointStateMsg();
        sensor_msg.header=new RosMessageTypes.Std.HeaderMsg();
        sensor_msg.header.stamp=ROSCommon.getFixedTimeStamp();
        var clock_msg=new RosMessageTypes.Rosgraph.ClockMsg();
        clock_msg.clock=sensor_msg.header.stamp;

        Debug.Log("seconds "+clock_msg.clock.sec+ "nano secs"+clock_msg.clock.nanosec);

        ros.Publish(clock_topic,sensor_msg);
        ros.Publish(clock_real_topic,clock_msg);
    }
}

where the function getFixedTimeStamp is:

static public  RosMessageTypes.BuiltinInterfaces.TimeMsg getFixedTimeStamp()
    {
        float time_since_start=Time.fixedTime;
        uint seconds=(uint)Math.Floor(time_since_start);
        uint nano_seconds=(uint)((time_since_start-(float)seconds)*10E9);
        RosMessageTypes.BuiltinInterfaces.TimeMsg time_stamp=new RosMessageTypes.BuiltinInterfaces.TimeMsg(seconds,nano_seconds);
        return time_stamp;
    }

Anyone has an idea of why this is happening? Thank you

Environment :

Raphtor commented 2 years ago

Ah, I was also having this issue. Could it be that seconds is being implicitly converted into an int from uint? In fact, my editor throws an error with your getFixedTimeStamp for that reason. This code works for me (Unity 2021.2.19f1, Mac, v0.7.0)

float time_since_start = Time.fixedTime;
int seconds = (int)Math.Floor(time_since_start);
uint nano_seconds = (uint)((time_since_start - (float)seconds) * 10E9);
TimeMsg time_stamp = new TimeMsg(seconds, nano_seconds);
return time_stamp;

However, I wanted unix time in order to align with other robotic systems. I did this by using system.DateTime and the unix time, which also should align that with system time that other systems might use.

protected TimeMsg GetTime()
    {
        DateTimeOffset dto = new DateTimeOffset(DateTime.Now);
        int intTime = (int) dto.ToUnixTimeSeconds();
        uint nanoTime = (uint) dto.ToUnixTimeMilliseconds() * 1000000;
        return new TimeMsg(intTime, nanoTime);
    }
mojervico commented 2 years ago

Thank you for you answer! But in my case, I was explicitly converting int to uint. Besides when debugging the Unity side, the seconds and nanoseconds displayed were correct. However, when publishing it as clockMsg at frequency of 100hz it when it appear the problem that it was not sending sequential timestep, weird is that the same value of the timestamp it was correctly published by the sensor_msgs/Jointstate type of my above code. If I lower the publishing frequency to 2Hz the clockMsg was okay.

mojervico commented 1 year ago

I finally discover that it was an error on my implementation when obtainning the nano seconds. Instead of multiplying by 10E9 the correct values was 1e9. Sorry for the inconvenient!! I'll close the issue