00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdio.h>
00023 #include <string.h>
00024 #include <math.h>
00025
00026 #include <aversive.h>
00027 #include <quadramp.h>
00028
00029 #define NEXT(n, i) (((n) + (i)/(n)) >> 1)
00030
00031 void quadramp_init(struct quadramp_filter * q)
00032 {
00033 uint8_t flags;
00034 IRQ_LOCK(flags);
00035 memset(q, 0, sizeof(*q));
00036 IRQ_UNLOCK(flags);
00037 }
00038
00039 void quadramp_set_2nd_order_vars(struct quadramp_filter * q,
00040 uint32_t var_2nd_ord_pos,
00041 uint32_t var_2nd_ord_neg)
00042 {
00043 uint8_t flags;
00044 IRQ_LOCK(flags);
00045 q->var_2nd_ord_pos = var_2nd_ord_pos;
00046 q->var_2nd_ord_neg = var_2nd_ord_neg;
00047 IRQ_UNLOCK(flags);
00048 }
00049
00050 void quadramp_set_1st_order_vars(struct quadramp_filter * q,
00051 uint32_t var_1st_ord_pos,
00052 uint32_t var_1st_ord_neg)
00053 {
00054 uint8_t flags;
00055 IRQ_LOCK(flags);
00056 q->var_1st_ord_pos = var_1st_ord_pos;
00057 q->var_1st_ord_neg = var_1st_ord_neg;
00058 IRQ_UNLOCK(flags);
00059 }
00060
00061
00062 uint8_t quadramp_is_finished(struct quadramp_filter *q)
00063 {
00064 return (q->previous_out == q->previous_in &&
00065 q->previous_var == 0);
00066 }
00067
00075 int32_t quadramp_do_filter(void * data, int32_t in)
00076 {
00077 struct quadramp_filter * q = data;
00078 int32_t d ;
00079 int32_t pos_target;
00080 int32_t var_1st_ord_pos = 0;
00081 int32_t var_1st_ord_neg = 0;
00082 int32_t var_2nd_ord_pos = 0;
00083 int32_t var_2nd_ord_neg = 0;
00084 int32_t previous_var, previous_out ;
00085
00086 if ( q->var_1st_ord_pos )
00087 var_1st_ord_pos = q->var_1st_ord_pos ;
00088
00089 if ( q->var_1st_ord_neg )
00090 var_1st_ord_neg = -q->var_1st_ord_neg ;
00091
00092 if ( q->var_2nd_ord_pos )
00093 var_2nd_ord_pos = q->var_2nd_ord_pos ;
00094
00095 if ( q->var_2nd_ord_neg )
00096 var_2nd_ord_neg = -q->var_2nd_ord_neg ;
00097
00098 previous_var = q->previous_var;
00099 previous_out = q->previous_out;
00100
00101 d = in - previous_out ;
00102
00103
00104 if ( d > 0 && var_2nd_ord_neg) {
00105 int32_t ramp_pos;
00106
00107
00108 ramp_pos = sqrt( (var_2nd_ord_neg*var_2nd_ord_neg)/4 - 2*d*var_2nd_ord_neg ) + var_2nd_ord_neg/2;
00109
00110 if(ramp_pos < var_1st_ord_pos)
00111 var_1st_ord_pos = ramp_pos ;
00112 }
00113
00114 else if (d < 0 && var_2nd_ord_pos) {
00115 int32_t ramp_neg;
00116
00117
00118
00119 ramp_neg = -sqrt( (var_2nd_ord_pos*var_2nd_ord_pos)/4 - 2*d*var_2nd_ord_pos ) - var_2nd_ord_pos/2;
00120
00121
00122 if(ramp_neg > var_1st_ord_neg)
00123 var_1st_ord_neg = ramp_neg ;
00124 }
00125
00126
00127
00128 if ( previous_var < var_1st_ord_pos ) {
00129
00130
00131
00132 if (var_2nd_ord_pos && ( var_1st_ord_pos - previous_var > var_2nd_ord_pos) )
00133 var_1st_ord_pos = previous_var + var_2nd_ord_pos ;
00134 }
00135
00136 else if ( previous_var > var_1st_ord_pos ) {
00137
00138
00139
00140 if (var_2nd_ord_neg && ( var_1st_ord_pos - previous_var < var_2nd_ord_neg) )
00141 var_1st_ord_pos = previous_var + var_2nd_ord_neg;
00142 }
00143
00144
00145
00146 if ( previous_var > var_1st_ord_neg ) {
00147
00148
00149
00150 if (var_2nd_ord_neg && ( var_1st_ord_neg - previous_var < var_2nd_ord_neg) )
00151 var_1st_ord_neg = previous_var + var_2nd_ord_neg ;
00152 }
00153
00154 else if ( previous_var < var_1st_ord_neg ) {
00155
00156
00157
00158 if (var_2nd_ord_pos && (var_1st_ord_neg - previous_var > var_2nd_ord_pos) )
00159 var_1st_ord_neg = previous_var + var_2nd_ord_pos;
00160 }
00161
00162
00163
00164
00165 if ( d > var_1st_ord_pos ) {
00166 pos_target = previous_out + var_1st_ord_pos ;
00167 previous_var = var_1st_ord_pos ;
00168 }
00169 else if ( d < var_1st_ord_neg ) {
00170 pos_target = previous_out + var_1st_ord_neg ;
00171 previous_var = var_1st_ord_neg ;
00172 }
00173 else {
00174 pos_target = previous_out + d ;
00175 previous_var = d ;
00176 }
00177
00178
00179 q->previous_var = previous_var;
00180 q->previous_out = pos_target;
00181 q->previous_in = in;
00182
00183 return pos_target ;
00184 }