xsenssupport / Xsens_MTi_ROS_Driver_and_Ntrip_Client

Xsens MTi ROS Driver and Ntrip Client, modified based on the 2023 official ROS Driver and added Ntrip Client
15 stars 11 forks source link

High Frequency data is buffered at 100Hz #3

Open ahmadSum1 opened 3 weeks ago

ahmadSum1 commented 3 weeks ago

The high-frequency topics are being buffered/clustered at 100hz. here is an example with an unmodified driver with the provided launch file:

Platform:

xsenssupport commented 3 weeks ago

Hi, We just updated the ROS2 driver to add the High Rate topic, so you could check the ros2 topic imu/acceleration_hr and imu/angular_velocity_hr for the 1000Hz high rate data, while for the 100Hz calibrated data, you could check the imu/data or imu/acceleration or imu/angular_velocity. Note that if you had selected too many data output types, you need to increase your baudrate to a much higher value, for example 2M, otherwise there will be a lot of data loss.(You could see the warning messages in this ros2 driver, and also in the message window in the MT Manager: Data Overflow.)

Also considering direct serial connection for high data rate and real time performance, for example direct UART connection to the UART pins of a RaspberryPi/Jetson devices.

Also notice that there might be some bug in the ros2 topic hz, while calculating the data rate, since we checked that there is no data loss when only selecting output acceleration_hr and angular_velocity_hr, but the data rate given by the ros2 topic hz is incorrect for the 1000Hz or 2000Hz(MTI-680) data output.

If you only use USB connection, consider use:

setserial /dev/ttyUSB0 low_latency
ahmadSum1 commented 3 weeks ago

Hi @xsenssupport , Thanks for the quick response. I have already tried most of what you said but in the end, I found that there is a hardcoded read buffer here: https://github.com/xsenssupport/Xsens_MTi_ROS_Driver_and_Ntrip_Client/blob/f21f1bafe731cf828ff2208a69101749d30bd0e6/src/xsens_mti_ros2_driver/lib/xspublic/xscontroller/serialcommunicator.cpp#L365 changed to

const int maxSz = XS_DEFAULT_READ_BUFFER_SIZE;

Then I had to significantly reduce the buffer size. https://github.com/xsenssupport/Xsens_MTi_ROS_Driver_and_Ntrip_Client/blob/7e2a47dd5c143d7ea8869b57422f3db24ba984ca/src/xsens_ros_mti_driver/lib/xspublic/xscontroller/iointerface.h#L48

Here is what it looks like with a buffer size 50bytes: image I guess the missing frames are due to buffer size misalignment.!?

ahmadSum1 commented 3 weeks ago

setserial /dev/ttyUSB0 low_latency

this essentially solves the issue upto 500hz without fiddling around with source code. 500hz_setusb_lowlatency_Screenshot from 2024-08-20 12-15-44

But at 1000hz, things are again buffered at around 500hz 1Khz_setserial_lowlatency_Screenshot from 2024-08-20 12-49-04

ahmadSum1 commented 3 weeks ago

As I understand, the large buffer size in the xsense driver is not an issue if the Linux serial port timer interrupt or timeout force triggers a data parsing in time. Seems like, the default is set at 10ms, hence the clustering behavior around 100hz. https://github.com/xsenssupport/Xsens_MTi_ROS_Driver_and_Ntrip_Client/blob/7e2a47dd5c143d7ea8869b57422f3db24ba984ca/src/xsens_ros_mti_driver/lib/xspublic/xscontroller/iointerface.h#L92

However,

If you only use USB connection, consider use:

setserial /dev/ttyUSB0 low_latency

this seems to only set this Linux mysterious timeout to be ~2ms.

xsenssupport commented 3 weeks ago

As I understand, the large buffer size in the xsense driver is not an issue if the Linux serial port timer interrupt or timeout force triggers a data parsing in time. Seems like, the default is set at 10ms, hence the clustering behavior around 100hz.

https://github.com/xsenssupport/Xsens_MTi_ROS_Driver_and_Ntrip_Client/blob/7e2a47dd5c143d7ea8869b57422f3db24ba984ca/src/xsens_ros_mti_driver/lib/xspublic/xscontroller/iointerface.h#L92

However,

If you only use USB connection, consider use:

setserial /dev/ttyUSB0 low_latency

this seems to only set this Linux mysterious timeout to be ~2ms.

As mentioned, it is not a problem of Xsens ROS Driver or Xspublic library, it is a problem of ros2 topic hz, you could simply google ros2 topic hz issue, and you could find a lot of results, including this one. You could verify the data rate by using the MT SDK's xda_public_cpp.

ahmadSum1 commented 3 weeks ago

Yes and No.

it is a problem of ros2 topic hz

It is not an issue related to ROS2 topic hz. It relates to Linux tick latency and how this ROS driver reads the data.

Solutions That I have tested so far (without having to patch the Linux kernel):

  1. Using USB low latency mode (works great up to 500hz)

    setserial /dev/ttyUSB0 low_latency

    • Fix the hardcoded buffer size and then
    • reduce XS_DEFAULT_READ_BUFFER_SIZE to 40~50 bytes, This forces data parsing and publishing to be faster. (tested with 1Khz, has more missing frames.)
xsenssupport commented 2 weeks ago

Hi,

I tested in with Raspberry Pi 5B, ubuntu 24.04, before using the set setserial command, the ros2 topic hz gives 683Hz, after using the setserial command, the data rate gives 1000Hz:

image

So there is no need to change any of the xspublic code, closing this issue.

ahmadSum1 commented 2 weeks ago

Hello, I am afraid, you have missed the real issue here.

I tested in with Raspberry Pi 5B, ubuntu 24.04, before using the set setserial command, the ros2 topic hz gives 683Hz, after using the setserial command, the data rate gives 1000Hz:

Could you please confirm if you checked the actual timing of the individual messages? The messages are buffered. So, even though the average frequency is 1000hz, the real data is clustered around 500hz(with low latency) or 100hz(by default).

image