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
00024 #include <aversive.h>
00025 #include <quadramp_derivate.h>
00026
00027
00028 void quadramp_derivate_init(struct quadramp_derivate_filter * q)
00029 {
00030 uint8_t flags;
00031 IRQ_LOCK(flags);
00032
00033 q->var_2nd_ord_pos = 1;
00034 q->var_2nd_ord_neg = 1;
00035 q->var_1st_ord_pos = 0;
00036 q->var_1st_ord_neg = 0;
00037
00038 q->previous_in_position = 0;
00039 q->previous_out_speed = 0;
00040
00041 q-> gain_anticipation= 0;
00042 q-> goal_window= 0;
00043
00044 q-> divisor = 1;
00045
00046 q-> pivot = 0;
00047
00048 IRQ_UNLOCK(flags);
00049 }
00050
00051
00052 void quadramp_derivate_set_gain_anticipation(struct quadramp_derivate_filter * q, uint16_t gain_anticipation)
00053 {
00054 uint8_t flags;
00055 IRQ_LOCK(flags);
00056 q->gain_anticipation = gain_anticipation;
00057 IRQ_UNLOCK(flags);
00058 }
00059
00060 void quadramp_derivate_set_goal_window(struct quadramp_derivate_filter * q, uint32_t goal_window)
00061 {
00062 uint8_t flags;
00063 IRQ_LOCK(flags);
00064 q->goal_window = goal_window;
00065 IRQ_UNLOCK(flags);
00066 }
00067
00068 void quadramp_derivate_set_2nd_order_vars(struct quadramp_derivate_filter * q, uint32_t var_2nd_ord_pos, uint32_t var_2nd_ord_neg)
00069 {
00070 uint8_t flags;
00071 IRQ_LOCK(flags);
00072 q->var_2nd_ord_pos = var_2nd_ord_pos;
00073 q->var_2nd_ord_neg = var_2nd_ord_neg;
00074 IRQ_UNLOCK(flags);
00075 }
00076
00077 void quadramp_derivate_set_1st_order_vars(struct quadramp_derivate_filter * q, uint32_t var_1st_ord_pos, uint32_t var_1st_ord_neg)
00078 {
00079 uint8_t flags;
00080 IRQ_LOCK(flags);
00081 q->var_1st_ord_pos = var_1st_ord_pos;
00082 q->var_1st_ord_neg = var_1st_ord_neg;
00083 IRQ_UNLOCK(flags);
00084 }
00085
00086
00087 void quadramp_derivate_set_divisor(struct quadramp_derivate_filter * q, uint8_t divisor)
00088 {
00089 uint8_t flags;
00090 IRQ_LOCK(flags);
00091
00092 q->divisor = divisor;
00093 q->divisor_counter = 1;
00094
00095 IRQ_UNLOCK(flags);
00096 }
00097
00098
00106 int32_t quadramp_derivate_do_filter(void * data, int32_t in_position)
00107 {
00108 struct quadramp_derivate_filter * q = data;
00109 int32_t position_pivot, speed, var_2nd_ord, acceleration_consign, speed_consign;
00110
00113 if( q->divisor != 1) {
00114 if (-- (q->divisor_counter) !=0 ) {
00115
00116 if(ABS( in_position ) < q->goal_window)
00117 q->previous_out_speed =0;
00118
00119 return q->previous_out_speed;
00120 }
00121
00122 q->divisor_counter = q->divisor;
00123 }
00124
00125
00126
00130 in_position = -in_position;
00131
00132
00133
00134 speed = in_position - q->previous_in_position;
00135
00136
00137
00140 if (speed >=0) {
00141 if(q->var_1st_ord_pos)
00142 MAX(speed , (q->var_1st_ord_pos * q-> divisor) );
00143 }
00144 else {
00145 if(q->var_1st_ord_neg)
00146 MIN(speed , (-(q->var_1st_ord_neg* q-> divisor)) );
00147 }
00148
00149
00150
00151
00158
00159 if (speed >=0)
00160 var_2nd_ord = q->var_2nd_ord_pos;
00161 else
00162 var_2nd_ord = q->var_2nd_ord_neg;
00163
00164
00165 position_pivot = (ABS(speed) * q->gain_anticipation) >>8 ;
00166
00167
00168 if(q->divisor != 1) {
00169 var_2nd_ord *= q-> divisor;
00170 position_pivot /= q-> divisor;
00171 }
00172
00173
00174 position_pivot += speed*speed /(2*var_2nd_ord);
00175
00176
00177 if(speed >=0)
00178 position_pivot = - position_pivot;
00179
00180
00181 q-> pivot = position_pivot;
00182
00190 if(position_pivot >= in_position)
00191 acceleration_consign = q->var_2nd_ord_pos;
00192 else
00193 acceleration_consign = -q->var_2nd_ord_neg;
00194
00195
00196
00198 speed_consign = q->previous_out_speed + acceleration_consign;
00199
00200 if (speed_consign >=0) {
00201 if(q->var_1st_ord_pos)
00202 MAX(speed_consign , q->var_1st_ord_pos);
00203 }
00204 else {
00205 if(q->var_1st_ord_neg)
00206 MIN(speed_consign , -q->var_1st_ord_neg);
00207 }
00208
00209
00211 if(ABS( in_position ) < q->goal_window)
00212 speed_consign=0;
00213
00215 q->previous_in_position = in_position;
00216 q->previous_out_speed = speed_consign;
00217
00218
00219 return speed_consign ;
00220 }