-
Notifications
You must be signed in to change notification settings - Fork 194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot stream transforms via the frameTransformClient
from Windows to Ubuntu because yarp::os::Time::now()
is platform dependent
#3038
Comments
I wonder if we could modify |
This issue has a big impact on all setups where windows machines have to communicate with linux machines. It may involve not only the frameTransform-related software but also other modules, such as camera/encoders synchronization. It must be noted that this issue cannot be caught by our CI which does not test communication between different os. |
What about defining a |
Even if this is tipically done in simulation when you use stream the gazebo clock throught a port, I do not think propagating a custom clock through the network is a good idea.
|
As this timestamp is meant to be interoperable with ROS, I think we can check which timestamp code is used in ROS and use that. |
See:
at this point, I lost where the actual |
No, apparently that function exists but then it is not used in the actual nodes that publish transform, see for example: https://github.com/ros2/geometry2/blob/e8a7223bb6a55c8116f439dbbc947d93885d29f9/tf2_ros/src/static_transform_broadcaster_node.cpp#L73C31-L73C34 , see also ros2/geometry2#67 . |
Ok, I found the code in ROS2 were they account for different epochs between Windows and Linux, exactly how we were discussing to do @S-Dafarra : |
The second link does not work for me |
You are right, I blindly copied it from the code. By looking in webarchive, the updated link is https://support.microsoft.com/en-us/topic/bf03df72-96e4-59f3-1d02-b6781002dc7f . |
Fixed upstream in ros2/rcutils#438 . |
I have tried to get the number of seconds since 1st January 1970. In order to test it, I started editing these lines
with the following: while (true) {
double t = yarp::os::Time::now();
auto currentTime = std::chrono::high_resolution_clock::now();
std::tm epochTimeInfo = {};
epochTimeInfo.tm_year = 1970 - 1900;
epochTimeInfo.tm_mon = 0;
epochTimeInfo.tm_mday = 1;
epochTimeInfo.tm_hour = 0;
epochTimeInfo.tm_min = 0;
epochTimeInfo.tm_sec = 0;
time_t epochTimeWithZone = std::mktime(&epochTimeInfo);
auto epochTimeUTC = std::mktime(std::gmtime(&epochTimeWithZone));
auto epochTimeManual = std::chrono::high_resolution_clock::from_time_t(epochTimeUTC);
auto epochTimeChrono = std::chrono::time_point<std::chrono::high_resolution_clock>{};
double seconds_since_epoch = std::chrono::duration<double>(currentTime - epochTimeManual).count();
double epochVariation = std::chrono::duration<double>(epochTimeChrono - epochTimeManual).count();
if (ros) {
int sec = (int) t;
int nsec = (int)((t-sec)*1e9);
yCInfo(COMPANION, "%d %d", sec, nsec);
} else {
yCInfo(COMPANION, "yarp %f -- since epoch %f -- epoch difference %f", t, seconds_since_epoch, epochVariation);
}
fflush(stdout);
clk.delay(0.1);
} but I get the following result
I have verified that the first number is coincident with https://www.epochconverter.com/clock. There is 2 hours difference I need to iron out. I suspect that there is a weird timezone difference applied when converting to a |
To fix the conversion issue, I checked how the while (true) {
double t = yarp::os::Time::now();
auto currentTime = std::chrono::high_resolution_clock::now();
std::tm epochTimeInfo = {};
epochTimeInfo.tm_year = 1970 - 1900;
epochTimeInfo.tm_mon = 0;
epochTimeInfo.tm_mday = 1;
epochTimeInfo.tm_hour = 0;
epochTimeInfo.tm_min = 0;
epochTimeInfo.tm_sec = 0;
time_t epochTimeWithZone = std::mktime(&epochTimeInfo);
auto epochTimeChrono = std::chrono::time_point<std::chrono::high_resolution_clock>{};
time_t epochTimeChrono_time_t = std::chrono::high_resolution_clock::to_time_t(epochTimeChrono);
time_t epochTimeChrono_time_t_UTC = std::mktime(std::gmtime(&epochTimeChrono_time_t));
auto utc_diff = epochTimeChrono_time_t - epochTimeChrono_time_t_UTC;
auto epochTimeManual = std::chrono::high_resolution_clock::from_time_t(epochTimeWithZone + utc_diff);
double seconds_since_epoch = std::chrono::duration<double>(currentTime - epochTimeManual).count();
double epochVariation = std::chrono::duration<double>(epochTimeChrono - epochTimeManual).count();
if (ros) {
int sec = (int) t;
int nsec = (int)((t-sec)*1e9);
yCInfo(COMPANION, "%d %d", sec, nsec);
} else {
yCInfo(COMPANION, "yarp %f -- since epoch %f -- epoch difference %f", t, seconds_since_epoch, epochVariation);
}
fflush(stdout);
clk.delay(0.1);
} and the result is
|
I tried the same code on Windows. Initially it was not compiling because i.e.while (true) {
double t = yarp::os::Time::now();
auto currentTime = std::chrono::system_clock::now();
std::tm epochTimeInfo = {};
epochTimeInfo.tm_year = 1970 - 1900;
epochTimeInfo.tm_mon = 0;
epochTimeInfo.tm_mday = 1;
epochTimeInfo.tm_hour = 0;
epochTimeInfo.tm_min = 0;
epochTimeInfo.tm_sec = 0;
time_t epochTimeWithZone = std::mktime(&epochTimeInfo);
auto epochTimeChrono = std::chrono::time_point<std::chrono::system_clock> {};
time_t epochTimeChrono_time_t = std::chrono::system_clock::to_time_t(epochTimeChrono);
time_t epochTimeChrono_time_t_UTC = std::mktime(std::gmtime(&epochTimeChrono_time_t));
auto utc_diff = epochTimeChrono_time_t - epochTimeChrono_time_t_UTC;
auto epochTimeManual = std::chrono::system_clock::from_time_t(epochTimeWithZone + utc_diff);
double seconds_since_epoch = std::chrono::duration<double>(currentTime - epochTimeManual).count();
double epochVariation = std::chrono::duration<double>(epochTimeChrono - epochTimeManual).count();
if (ros) {
int sec = (int)t;
int nsec = (int)((t - sec) * 1e9);
yCInfo(COMPANION, "%d %d", sec, nsec);
} else {
yCInfo(COMPANION, "yarp %f -- since epoch %f -- epoch difference %f", t, seconds_since_epoch, epochVariation);
}
fflush(stdout);
clk.delay(0.1);
} I got the following output:
The interesting part is that now also on Windows the epoch difference is zero. So I tried to change
to return std::chrono::time_point_cast<std::chrono::duration<double>>(std::chrono::system_clock::now()).time_since_epoch().count(); as @traversaro hinted, and I obtained
So I guess that the problem was with
(This also explains why In fact, I tried to change to
and reading its documentation
which explains why it is so small. Indeed, after a reboot of the machine (not after power on/power off) I obtained
This behavior is the same with |
frameTransformClient
from Windows to Ubuntu because ``yarp::os::Time::now() is platform dependentframeTransformClient
from Windows to Ubuntu because yarp::os::Time::now()
is platform dependent
…k instead of std::chrono::high_resolution_clock. This makes yarp timestamps comparable between windows and linux machines. See issue robotology#3038
I applied #3041 locally and the problem with the |
…k instead of std::chrono::high_resolution_clock. This makes yarp timestamps comparable between windows and linux machines. See issue robotology#3038
Describe the bug
We have two PCs, one running Windows 11 to access Windows device, and one running Ubuntu, connected to the same network. The Windows PC runs the
frameTransformServer
device and an application publishes transforms. These transforms are then read on the Ubuntu machine using the following configurationWhen we attempt to read the transform, we get an error of the type
By enabling the verbosity of the
FrameTransformStorage
(basically commenting the linesyarp/src/devices/frameTransformStorage/FrameTransformStorage.cpp
Lines 31 to 32 in e79029a
we obtain the following messages
It is possible to notice that there are two largely different timestamps:
1699376406.449361
, and1218348.235078
.1699376406.449361
is the Unix epoch (see https://www.epochconverter.com/clock). We instead verified that1218348.235078
is the output ofyarp::os::Time::now()
on the Windows machine.Indeed, the Windows epoch is completely different: https://devblogs.microsoft.com/oldnewthing/20090306-00/?p=18913
This might be related to the fact that
time_since_epoch
, used inyarp/src/libYARP_os/src/yarp/os/SystemClock.cpp
Line 36 in e79029a
is guaranteed to be relative to the UNIX epoch only since C++20: https://stackoverflow.com/a/6012671
With @randaz81, we also tried to compile YARP with C++20 on Windows, but given the corresponding high number of issues, we paused the activity.
To Reproduce
Steps to reproduce the behavior:
Run
yarp::os::Time::now()
on Windows and Ubuntu to check the difference.Expected behavior
A clear and concise description of what you expected to happen.
If
yarp::os::Time::now()
returns the same on each machine, then also theframeTransformClient
issue should be solved.Screenshots
If applicable, add screenshots to help explain your problem.
Configuration (please complete the following information):
Additional context
Add any other context about the problem here.
The text was updated successfully, but these errors were encountered: