void aipImageInterpolation(interpolation_t method, float *data, int npf, int npm, float *cdata, int cnpf, int cnpm ) { /* * Memory allocation */ float *buf = new float[npm]; float *cbuf = new float[cnpm]; float *buf2D = new float[npf*cnpm]; /* * Interpolation along "medium" axis */ int i, j; for( j=0; j<npf; j++ ){ for( i=0; i<npm; i++ ){ buf[i] = data[ i*npf + j ]; } if( method == INTERP_CUBIC_SPLINE ) { cubic_spline_interpolation( npm, buf, cnpm, cbuf ); } else { simple_interpolation( npm, buf, cnpm, cbuf ); } for( i=0; i<cnpm; i++ ){ buf2D[i*npf+j] = cbuf[i]; } } /* * Interpolation along "fast" axis */ for( j=0; j<cnpm; j++ ){ if( method == INTERP_CUBIC_SPLINE ) { cubic_spline_interpolation(npf, &buf2D[j*npf], cnpf, &cdata[j*cnpf]); }else{ simple_interpolation(npf, &buf2D[j*npf], cnpf, &cdata[j*cnpf]); } } delete [] buf; delete [] cbuf; delete [] buf2D; }
// Реализует функцию УОЗ от оборотов для пуска двигателя // Возвращает значение угла опережения в целом виде * 32, 2 * 16 = 32. int16_t start_function(struct ecudata_t* d) { int16_t i, i1, rpm = d->sens.inst_frq; if (rpm < 200) rpm = 200; //200 - минимальное значение оборотов i = (rpm - 200) / 40; //40 - шаг по оборотам if (i >= 15) i = i1 = 15; else i1 = i + 1; return simple_interpolation(rpm, _GB(&d->fn_dat->f_str[i]), _GB(&d->fn_dat->f_str[i1]), (i * 40) + 200, 40); }
// Реализует функцию УОЗ от оборотов для холостого хода // Возвращает значение угла опережения в целом виде * 32. 2 * 16 = 32. int16_t idling_function(struct ecudata_t* d) { int8_t i; int16_t rpm = d->sens.inst_frq; //находим узлы интерполяции, вводим ограничение если обороты выходят за пределы for(i = 14; i >= 0; i--) if (d->sens.inst_frq >= PGM_GET_WORD(&f_slots_ranges[i])) break; if (i < 0) {i = 0; rpm = 600;} return simple_interpolation(rpm, _GB(&d->fn_dat->f_idl[i]), _GB(&d->fn_dat->f_idl[i+1]), PGM_GET_WORD(&f_slots_ranges[i]), PGM_GET_WORD(&f_slots_length[i])); }
int16_t idl_coolant_rpm_function(struct ecudata_t* d) { int16_t i, i1, t = d->sens.temperat; if (!d->param.tmp_use) return d->param.idling_rpm*16; //обороты хх = тем что заданы в окне оборотов РХХ, если блок неукомплектован ДТОЖ-ом //-30 - минимальное значение температуры if (t < TEMPERATURE_MAGNITUDE(-30)) t = TEMPERATURE_MAGNITUDE(-30); //10 - шаг между узлами интерполяции по температуре i = (t - TEMPERATURE_MAGNITUDE(-30)) / TEMPERATURE_MAGNITUDE(10); if (i >= 15) i = i1 = 15; else i1 = i + 1; return simple_interpolation(t, idl_collant_rpm_t[i], idl_collant_rpm_t[i1], (i * TEMPERATURE_MAGNITUDE(10)) + TEMPERATURE_MAGNITUDE(-30), TEMPERATURE_MAGNITUDE(10)); }
//Реализует функцию коррекции УОЗ по температуре(град. Цельсия) охлаждающей жидкости // Возвращает значение угла опережения в целом виде * 32, 2 * 16 = 32. int16_t coolant_function(struct ecudata_t* d) { int16_t i, i1, t = d->sens.temperat; if (!d->param.tmp_use) return 0; //нет коррекции, если блок неукомплектован ДТОЖ-ом //-30 - минимальное значение температуры if (t < TEMPERATURE_MAGNITUDE(-30)) t = TEMPERATURE_MAGNITUDE(-30); //10 - шаг между узлами интерполяции по температуре i = (t - TEMPERATURE_MAGNITUDE(-30)) / TEMPERATURE_MAGNITUDE(10); if (i >= 15) i = i1 = 15; else i1 = i + 1; return simple_interpolation(t, _GB(&d->fn_dat->f_tmp[i]), _GB(&d->fn_dat->f_tmp[i1]), (i * TEMPERATURE_MAGNITUDE(10)) + TEMPERATURE_MAGNITUDE(-30), TEMPERATURE_MAGNITUDE(10)); }
//Coolant sensor is thermistor (тип датчика температуры - термистор) //Note: We assume that voltage on the input of ADC depend on thermistor's resistance linearly. //Voltage on the input of ADC can be calculated as following: // U3=U1*Rt*R2/(Rp(Rt+R1+R2)+Rt(R1+R2)); // Rt - thermistor, Rp - pulls up thermistor to voltage U1, // R1,R2 - voltage divider resistors. int16_t thermistor_lookup(uint16_t adcvalue) { int16_t i, i1; //Voltage value at the start of axis in ADC discretes (значение напряжения в начале оси в дискретах АЦП) uint16_t v_start = PGM_GET_WORD(&fw_data.exdata.cts_vl_begin); //Voltage value at the end of axis in ADC discretes (значение напряжения в конце оси в дискретах АЦП) uint16_t v_end = PGM_GET_WORD(&fw_data.exdata.cts_vl_end); uint16_t v_step = (v_end - v_start) / (THERMISTOR_LOOKUP_TABLE_SIZE - 1); if (adcvalue < v_start) adcvalue = v_start; i = (adcvalue - v_start) / v_step; if (i >= THERMISTOR_LOOKUP_TABLE_SIZE-1) i = i1 = THERMISTOR_LOOKUP_TABLE_SIZE-1; else i1 = i + 1; return (simple_interpolation(adcvalue, PGM_GET_WORD(&fw_data.exdata.cts_curve[i]), PGM_GET_WORD(&fw_data.exdata.cts_curve[i1]), (i * v_step) + v_start, v_step)) >> 4; }
/*============================================================== Image ( 2D data ) interpolation data: input data npf: data size at fast dimension of input data npm: data size at medium dimension of input data cdata: output data cnpf: data size at fast dimension of output data cnpm: data size at medium dimension of output data method: SIMPLE or CUBIC_SPLINE minus: PASSASMINUS or CONV2ZERO RETURN value is always OK(!) ===============================================================*/ int image_2D_interpolation( Interpolation_method method, Minusval_type minus, float *data, int npf, int npm, float *cdata, int cnpf, int cnpm ) { /* * Memory allocation */ float *buf = new float[npm]; float *cbuf = new float[cnpm]; float *buf2D = new float[npf*cnpm]; /* * Interpolation along "medium" axis */ int i, j; for( j=0; j<npf; j++ ){ for( i=0; i<npm; i++ ){ buf[i] = data[ i*npf + j ]; } if( method == CUBIC_SPLINE ) { cubic_spline_interpolation( npm, buf, cnpm, cbuf ); }else{ simple_interpolation( npm, buf, cnpm, cbuf ); } if( minus == CONV2ZERO ){ for( i=0; i<cnpm; i++ ){ if( cbuf[i] < 0 ) buf2D[i*npf+j] = 0; else buf2D[i*npf+j] = cbuf[i]; } }else{ for( i=0; i<cnpm; i++ ){ buf2D[i*npf+j] = cbuf[i]; } } } /* * Interpolation along "fast" axis */ for( j=0; j<cnpm; j++ ){ if( method == CUBIC_SPLINE ) { cubic_spline_interpolation(npf, &buf2D[j*npf], cnpf, &cdata[j*cnpf]); }else{ simple_interpolation(npf, &buf2D[j*npf], cnpf, &cdata[j*cnpf]); } if( minus == CONV2ZERO ){ for( i=0; i<cnpf; i++ ){ if( cdata[i+j*cnpf] < 0 ) cdata[i+j*cnpf] = 0; } } } delete [] buf; delete [] cbuf; delete [] buf2D; return OK; }