From: Chris R. <gi...@gi...> - 2013-01-26 17:34:11
|
Make pid's idea of following error match motion's Motion generates a new commanded position each servo cycle. It expects the machine to move such that at the next period, it will be at that new target. It calculates ferror accordingly (this period's feedback vs last period's command.) Until now, pid didn't agree about what ferror meant: it would read the commanded and feedback positions simulatneously and call that difference the following error. This made it disagree with motion by the distance moved in one period, which gave an ferror discrepancy proportional to velocity. Unfortunately this fix has to be optional, at least in the release branch, because it will affect existing pid tunings. http://git.linuxcnc.org/?p=linuxcnc.git;a=commitdiff;h=645ad98 --- src/hal/components/pid.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/hal/components/pid.c b/src/hal/components/pid.c index 259d7d6..a190b0a 100644 --- a/src/hal/components/pid.c +++ b/src/hal/components/pid.c @@ -198,6 +198,7 @@ typedef struct { /* pin: the time the output has been saturated */ hal_bit_t *index_enable; /* pin: to monitor for step changes that would otherwise screw up FF */ + hal_bit_t *error_previous_target; /* pin: measure error as new position vs previous command, to match motion's ideas */ char prev_ie; } hal_pid_t; @@ -312,7 +313,11 @@ static void calc_pid(void *arg, long period) command = *(pid->command); feedback = *(pid->feedback); /* calculate the error */ - tmp1 = command - feedback; + if (*(pid->error_previous_target)) { + tmp1 = pid->prev_cmd - feedback; + } else { + tmp1 = command - feedback; + } /* store error to error pin */ *(pid->error) = tmp1; /* apply error limits */ @@ -592,6 +597,11 @@ static int export_pid(hal_pid_t * addr, char * prefix) if (retval != 0) { return retval; } + retval = hal_pin_bit_newf(HAL_IN, &(addr->error_previous_target), comp_id, + "%s.error-previous-target", prefix); + if (retval != 0) { + return retval; + } /* export optional parameters */ if (debug > 0) { retval = hal_pin_float_newf(HAL_OUT, &(addr->error_i), comp_id, |