ros-industrial / abb_libegm

A C++ library for interfacing with ABB robot controllers supporting Externally Guided Motion (689-1)
BSD 3-Clause "New" or "Revised" License
96 stars 54 forks source link

Clear Server Buffered Messages #53

Closed AbdelrhmanBassiouny closed 5 years ago

AbdelrhmanBassiouny commented 5 years ago

I tried a lot of different trajectories each with different velocities and number of points, the robot doesn't start motion until after a certain number of messages(always between 70 to 80).

I tried a very simple solution to add 70 points with zero velocity before the actual trajectory points, and the number of messages before starting robot motion increased by 70, so it seems to be aware of the velocity change in the sent data, not just waiting for this certain number of messages.

I am using joint mode, with velocity only control(I also tried position only outputs). I am using egm controller interface not the trajectory interface.

Also it seems that the sent messages aren't ignored because if they were it would have resulted in a Dynamic Load, which could mean that they are stored in a buffer.

Any help would be appreciated, thanks.

AbdelrhmanBassiouny commented 5 years ago

I have found the cause, it seems when the Rapid command EGMRunJoint is executed the controller starts sending messages immediatly and these messages if not recieved by the c++ egm controller interface like this: Server.wait_for_message() Server.read(&Input) the messages will aggregate in a buffer(with a limited size) and i have to read all those previous messages before i get the most recently sent or be synchronized with the controller.

also trying to write anything during reading the buffered without adding any custom delays will send a;ot pf outputs to the controller in a very short time that will usually result in a dynamic load.

The buffered messages are read much faster than the controller specified rate(4,8,12,..etc).

So the only thing i could think of since i can't find where is this buffer or how to clear it, is to measure the time between each 2 consecutive reads if it's smaller than a certain value then it was an old message until i am synchronized with the controller and Server.wait_for_message() takes approximately the specified sampling time.

I hope there's a better solution to this.

AbdelrhmanBassiouny commented 5 years ago

I found another way, which is to make sure that the EGM Server starts first and be waiting for the client, then run the EGMRunJoint command in the rapid code, this will ensure synchronization from the begining.

I was doing the opposite, i first run EGMRunJoint (using RWS library) with EGMSetupUC having a very large "comm_timeout", then start the egm server, this will surely recreate the problem.

I think it was my mistake to run the client first before the server, but i also think having a way to handle this case of having too many buffered messages wouldn't be bad.

jontje commented 5 years ago

Hi @BidoMan,

FYI: I am already on my vacation, but here are a few thoughts before my mind completely enters holiday mode ✈️🌞

So the only thing i could think of since i can't find where is this buffer or how to clear it, is to measure the time between each 2 consecutive reads if it's smaller than a certain value then it was an old message until i am synchronized with the controller and Server.wait_for_message() takes approximately the specified sampling time.

All interface classes are using a boost asynchronous UDP socket for receiving/sending EGM messages. The socket is created during instantization in egm_udp_server.cpp.

One idea could be to check if there are any messages in the socket's buffer and empty it, before starting with the asynchronous receives.

Otherwise, I guess there might be some socket options that could be helpful, but I have not looked into that.

I found another way, which is to make sure that the EGM Server starts first and be waiting for the client, then run the EGMRunJoint command in the rapid code, this will ensure synchronization from the begining.

This is how I always do it, and I can clarify this in the readme or in some examples. Sorry for the lack of instructions!

AbdelrhmanBassiouny commented 5 years ago

Hi @jontje I hope you enjoy your holiday, thank you for your response. And yes, i think adding it to the readme will be great.

gavanderhoorn commented 5 years ago

@jontje: would you want to create a separate issue to track the desired addition to the readme you mention?

gavanderhoorn commented 5 years ago

Tracking in #60.