ros-industrial / staubli_val3_driver

ROS-Industrial (simple message) driver for Stäubli CS8 and CS9 robot controllers (VAL 3 application)
Apache License 2.0
26 stars 21 forks source link

Clear trajectorty/motion buffer to not execute stale commands #31

Open Shoghairg opened 3 years ago

Shoghairg commented 3 years ago

Hello,

I am currently running a tx90xl and send trajectory messages to the arm by creating a publisher to generate custom trajectories to send to industrial robot client. The publish rate varies and is sometimes dependent on subscribed topic and other processes. The progress of the arm falls far behind the trajectory and motion buffer and the arm inevitable executes stale commands as it tries to clear the buffer. I would like to be able to send commands at any rate and have the arm execute the latest it receives and not store all of them to execute.

I am not familiar with val3 and have tried to edit the pgx files to clear the buffers or to change the size but have not been successful. I add the following lines to after the movej command in motionControl call libQueueFuncs:clear(qTrajPtBuffer) call libQueueFuncs:clear(qMoveBuffer) The buffer still does not clear to only execute new trajectories it receives.

Any help/suggestions would be much appreciated!

gavanderhoorn commented 3 years ago

I am currently running a tx90xl and send trajectory messages to the arm by creating a publisher to generate custom trajectories to send to industrial robot client

if at all possible, I'd advice using the action client to send JointTrajectionAction goals instead of using the topic interface.

It will result in much more predictable behaviour, and makes scheduling of motions easier, more efficient and less dependent on timing. Coordination with external nodes is also much easier, as actions follow a very well defined control flow.

The publish rate varies and is sometimes dependent on subscribed topic and other processes. The progress of the arm falls far behind the trajectory and motion buffer and the arm inevitable executes stale commands as it tries to clear the buffer.

see my previous comment.

I would like to be able to send commands at any rate and have the arm execute the latest it receives and not store all of them to execute.

the driver is not really suited for on-line streaming approaches I'm afraid. It can be done, but by default it's not properly configured for it.

The design is optimised for transmitting trajectories to the controller and executing them. Then sending another trajectory, and executing that. Etc.

You seem to be using it as an online, real-time external motion interface.

I believe that's the reason you are running into the problem you describe.

An additional complication is that streaming control will require close cooperation between the producer (of trajectory points) and consumer. Both in terms of taking motion smoothness into account as well as coordination in time (ie: don't send too many points in advance, keep the buffer at a certain level, only send new points if others have been processed, etc).

I am not familiar with val3 and have tried to edit the pgx files to clear the buffers or to change the size but have not been successful. I add the following lines to after the movej command in motionControl call libQueueFuncs:clear(qTrajPtBuffer) call libQueueFuncs:clear(qMoveBuffer) The buffer still does not clear to only execute new trajectories it receives.

Perhaps @marshallpowell97 can provide some insight.

Shoghairg commented 3 years ago

if at all possible, I'd advice using the action client to send JointTrajectionAction goals instead of using the topic interface.

We had attempted to use the JointTrajectionAction initially, this slowed down our application much more than desired.

the driver is not really suited for on-line streaming approaches I'm afraid. It can be done, but by default it's not properly configured for it.

I see, would you possibly have any recommendations on how to adjust for close to an online streaming approach? We have been trying to resetMotion() intermittently or using an alterMovej() to execute command instead of movej . We also tested with a waitendMove() to block out other tasks such as pushing to the buffer so the next executed would be the latest. The issue with waitendMove() is that we would like to keep blending in our implementation. The alterMovej() does not eliminate the issue of executing stale commands fully, however, did improve it somewhat.

An additional complication is that streaming control will require close cooperation between the producer (of trajectory points) and consumer. Both in terms of taking motion smoothness into account as well as coordination in time (ie: don't send too many points in advance, keep the buffer at a certain level, only send new points if others have been processed, etc).

That is something we may do. We have been exploring changes in the val3 side initially, attempting to essentially not fill the buffer even if a command was sent unless the previous one has been completed. That was also because, we are attempting to possibly implement a cancellation of the current motion if a new one is received. Our motion commands are generally limited to small displacements of the end effector and not larger motions. I understand we may be pushing what the current driver is setup to do but any suggestions would be appreciated.