Beckhoff / ADS

Beckhoff protocol to communicate with TwinCAT devices.
MIT License
491 stars 193 forks source link

Async WriteReqEx #215

Closed captain-yoshi closed 9 months ago

captain-yoshi commented 9 months ago

I am controlling a robot and need to exchange data at 1kHz. For receiving data, we use the AdsNotification which works well. For sending the data, we use the WriteReqEx function which is synchronuous, e.x. it will send the data and wait for the response. This process can take up from 1 to 2 msec (roundtrip). I don't need to wait for the response (we use a watchdog).

What I want is the ability to send the data without waiting for the response (similar to the AdsNotification). Is there an async WriteReqEx in the current API ? Could you give pointers on how to achieve this otherwise ?

error = route_->WriteReqEx(ADSIGRP_SYM_VALBYHND,      // IndexGroup
                           *(handle_command_->get()), // IndexOffset
                           write_len,                 // BufferLength
                           (void *)&buffer_command_); // WriteBuffer
pbruenn commented 9 months ago

ADS runs over TCP so fire & forget like you could do with UDP is not possible. At least your TCP send would wait for the ACK.
If you don't care about the responses, you can either try SetTimeout(0) and/or build a queue, setup a pool of worker threads and let them send out the request.

EDIT: you might need to replace this https://github.com/Beckhoff/ADS/blob/d7ada1228c68a7c4b2b86d357720ed8f6e76662c/AdsLib/standalone/AmsConnection.cpp#L207 with a return; to work

captain-yoshi commented 9 months ago

Thanks for the detailed answer ! I will try the two options and report back.

I currently have an AdsNotification callback, will setting the SetTimeout(0) affect it ?

captain-yoshi commented 9 months ago

When using a pool of worker threads I get this :

[ERROR] [1694658053.675123296]: AdsException message: Ads operation failed with error code -1.
2023-09-13T22:20:53-0400 Warning: Port: 30000 already in use as 0x7fb3c5ffaba0

But it seems to work... On linux, I increment a watchdog and log this variable in twincat. When analyzing the data, I only miss 2 samples for the duration of the logging (4002 cycles).

Before, I missed 50 samples for the same amount of cycles.

pbruenn commented 9 months ago

Try to use different "source" AmsPorts for your workerthreads. e.g. create an AdsDevice per thread

captain-yoshi commented 9 months ago

Great! No more samples missed with 10 worker threads.

Thanks again for pointing me to the right direction :)