Adjust refclock filter parameters
Drop only about 40 percent of samples, change default length to 64, require at least 4 samples between polls (or full filter for lengths below 4).
This commit is contained in:
parent
7fb0598b50
commit
fc1514db04
3 changed files with 50 additions and 17 deletions
|
@ -2287,9 +2287,11 @@ driver name and the number of the refclock are used as refid. Each
|
|||
refclock has to use an unique refid.
|
||||
@item filter
|
||||
This option sets the length of the median filter which is used to
|
||||
reduce noise. With each poll about half of the stored samples are
|
||||
reduce noise. With each poll about 40 percent of the stored samples is
|
||||
discarded and one final sample is calculated as average of the
|
||||
remaining samples. The default is 15.
|
||||
remaining samples. If the length is 4 or above, at least 4 samples
|
||||
have to be collected between polls. For lengths below 4, the filter
|
||||
has to be full. The default is 64.
|
||||
@item rate
|
||||
PPS signal frequency (in Hz). This option only controls how the
|
||||
received pulses are aligned. To actually receive more than one
|
||||
|
|
2
conf.c
2
conf.c
|
@ -448,7 +448,7 @@ parse_refclock(const char *line)
|
|||
|
||||
poll = 4;
|
||||
dpoll = 0;
|
||||
filter_length = 15;
|
||||
filter_length = 64;
|
||||
pps_rate = 0;
|
||||
offset = 0.0;
|
||||
delay = 1e-9;
|
||||
|
|
59
refclock.c
59
refclock.c
|
@ -210,9 +210,6 @@ RCL_AddRefclock(RefclockParameters *params)
|
|||
inst->pps_rate = 0;
|
||||
}
|
||||
|
||||
if (inst->driver_poll > inst->poll)
|
||||
inst->driver_poll = inst->poll;
|
||||
|
||||
if (params->ref_id)
|
||||
inst->ref_id = params->ref_id;
|
||||
else {
|
||||
|
@ -222,6 +219,22 @@ RCL_AddRefclock(RefclockParameters *params)
|
|||
inst->ref_id = ref[0] << 24 | ref[1] << 16 | ref[2] << 8 | ref[3];
|
||||
}
|
||||
|
||||
if (inst->driver->poll) {
|
||||
int max_samples;
|
||||
|
||||
if (inst->driver_poll > inst->poll)
|
||||
inst->driver_poll = inst->poll;
|
||||
|
||||
max_samples = 1 << (inst->poll - inst->driver_poll);
|
||||
if (max_samples < params->filter_length) {
|
||||
if (max_samples < 4) {
|
||||
LOG(LOGS_WARN, LOGF_Refclock, "Setting filter length for %s to %d",
|
||||
UTI_RefidToString(inst->ref_id), max_samples);
|
||||
}
|
||||
params->filter_length = max_samples;
|
||||
}
|
||||
}
|
||||
|
||||
if (inst->driver->init)
|
||||
if (!inst->driver->init(inst)) {
|
||||
LOG_FATAL(LOGF_Refclock, "refclock %s initialisation failed", params->driver_name);
|
||||
|
@ -691,28 +704,46 @@ filter_select_samples(struct MedianFilter *filter)
|
|||
if (filter->used < 1)
|
||||
return 0;
|
||||
|
||||
/* for lengths below 4 require full filter,
|
||||
for 4 and above require at least 4 samples */
|
||||
if ((filter->length < 4 && filter->used != filter->length) ||
|
||||
(filter->length >= 4 && filter->used < 4))
|
||||
return 0;
|
||||
|
||||
selected = filter->selected;
|
||||
|
||||
for (i = 1, min_dispersion = filter->samples[0].dispersion; i < filter->used; i++) {
|
||||
if (min_dispersion > filter->samples[i].dispersion)
|
||||
min_dispersion = filter->samples[i].dispersion;
|
||||
if (filter->used > 4) {
|
||||
/* select samples with dispersion better than 1.5 * minimum */
|
||||
|
||||
for (i = 1, min_dispersion = filter->samples[0].dispersion; i < filter->used; i++) {
|
||||
if (min_dispersion > filter->samples[i].dispersion)
|
||||
min_dispersion = filter->samples[i].dispersion;
|
||||
}
|
||||
|
||||
for (i = j = 0; i < filter->used; i++) {
|
||||
if (filter->samples[i].dispersion <= 1.5 * min_dispersion)
|
||||
selected[j++] = i;
|
||||
}
|
||||
} else {
|
||||
j = 0;
|
||||
}
|
||||
|
||||
/* select samples with dispersion better than 1.5 * minimum */
|
||||
for (i = j = 0; i < filter->used; i++) {
|
||||
if (filter->samples[i].dispersion <= 1.5 * min_dispersion)
|
||||
selected[j++] = i;
|
||||
}
|
||||
if (j < 4) {
|
||||
/* select all samples */
|
||||
|
||||
assert(j > 0);
|
||||
for (j = 0; j < filter->used; j++)
|
||||
selected[j] = j;
|
||||
}
|
||||
|
||||
/* and sort their indices by offset */
|
||||
tmp_sorted_array = filter->samples;
|
||||
qsort(selected, j, sizeof (int), sample_compare);
|
||||
|
||||
/* select half of the samples closest to the median */
|
||||
/* select 60 percent of the samples closest to the median */
|
||||
if (j > 2) {
|
||||
from = (j + 2) / 4;
|
||||
from = j / 5;
|
||||
if (from < 1)
|
||||
from = 1;
|
||||
to = j - from;
|
||||
} else {
|
||||
from = 0;
|
||||
|
|
Loading…
Reference in a new issue