[etherlab-users] Patch for Distributed Clock

Jun Yuan j.yuan at rtleaders.com
Fri Feb 1 17:53:35 CET 2013


Hi,

I've been testing Graeme Foot's DC Patch, which had already been added
into the etherlab master source by Florian. My system is Xenomai 2.6.1
+ Linux 2.6.37.6 + Etherlab(2498:9cdd7669dc0b at stable1.5).

First of all, a big thanks to Graeme Foot. It is a brilliant idea to
update the master cycle to match the ref slave time, and this works
wonderful! Great job! My servos run very stable now without any sync
problem. Thank you!

The little problem I found in the patch, however, is

timeDiff = ((timeDiff + (scanTimeNS/2)) % scanTimeNS) - (scanTimeNS/2);

This code doesn't work as it should, especially when timeDiff is negative.

And to the question that why "the time difference returned by
ecrt_rtdm_master_sync_slave_clocks_diff() is often one period out",
this was because that the correction made to the slave system_time was
wrong, see my last email 'Calculation of time_diff in
ec_fsm_master_dc_offset()'.

Regards,
Jun


diff -r 9cdd7669dc0b examples/rtai_rtdm_dc/main.c
--- a/examples/rtai_rtdm_dc/main.c    Thu Jan 10 17:36:41 2013 +0100
+++ b/examples/rtai_rtdm_dc/main.c    Fri Feb 01 17:38:29 2013 +0100
@@ -236,8 +236,9 @@
     prev_dc_diff_ns = dc_diff_ns;

     // normalise the time diff
-    dc_diff_ns =
-        ((dc_diff_ns + (cycle_ns / 2)) % cycle_ns) - (cycle_ns / 2);
+    dc_diff_ns = dc_diff_ns >= 0 ?
+            ((dc_diff_ns + (int32_t)(cycle_ns / 2)) %
(int32_t)cycle_ns) - (cycle_ns / 2) :
+            ((dc_diff_ns - (int32_t)(cycle_ns / 2)) %
(int32_t)cycle_ns) - (cycle_ns / 2) ;

     // only update if primary master
     if (dc_started) {
@@ -249,8 +250,9 @@

         if (dc_filter_idx >= DC_FILTER_CNT) {
             // add rounded delta average
-            dc_adjust_ns +=
-                ((dc_delta_total_ns + (DC_FILTER_CNT / 2)) / DC_FILTER_CNT);
+            dc_adjust_ns += dc_delta_total_ns >= 0 ?
+                ((dc_delta_total_ns + (DC_FILTER_CNT / 2)) / DC_FILTER_CNT) :
+                ((dc_delta_total_ns - (DC_FILTER_CNT / 2)) / DC_FILTER_CNT) ;

             // and add adjustment for general diff (to pull in drift)
             dc_adjust_ns += sign(dc_diff_total_ns / DC_FILTER_CNT);



More information about the Etherlab-users mailing list