bs_bcu_app/kit/kit_table.c

236 lines
6.6 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "kit_table.h"
//根据数据类型(1字节 2字节 4字节)来查表
KitResult kit_table_get_data(TabItem* item, uint8_t idx, int32_t * value)
{
KitResult res = kKitResult_ParamErr;
if ((item != NULL) && (item->tab != NULL) && (idx < item->len))
{
if (item->type == kTabDataType_8Bit)
{
*value = ((int8_t *)item->tab)[idx];
}
else if (item->type == kTabDataType_16Bit)
{
*value = ((int16_t*)item->tab)[idx];
}
else
{
*value = ((int32_t*)item->tab)[idx];
}
res = kKitResult_Ok;
}
return res;
}
//根据数据类型(1字节 2字节 4字节)来写数据
KitResult kit_table_set_data(TabItem* item, uint8_t idx, int32_t value)
{
KitResult res = kKitResult_ParamErr;
if ((item != NULL) && (item->tab != NULL) && (idx < item->len))
{
if (item->type == kTabDataType_8Bit)
{
((int8_t*)item->tab)[idx] = value;
}
else if (item->type == kTabDataType_16Bit)
{
((int16_t*)item->tab)[idx] = value;
}
else
{
((int32_t*)item->tab)[idx] = value;
}
res = kKitResult_Ok;
}
return res;
}
//返回kKitResult_OutRange 数据超出上下限
KitResult kit_table_search_index(TabItem *item, int32_t input_value, uint8_t * left_idx, uint8_t * right_idx)
{
KitResult res = kKitResult_ParamErr;
uint8_t end;
int32_t i, v1, v2;
if ((item != NULL) && (item->len > 1))
{
end = item->len - 1;
//查找两端数据
if ((kit_table_get_data(item, 0, &v1) == kKitResult_Ok)
&& (kit_table_get_data(item, end, &v2) == kKitResult_Ok))
{
if (((v1 < v2) && (input_value < v1)) || ((v1 > v2) && (input_value > v1)))
{
*left_idx = *right_idx = 0;
res = kKitResult_OutRange;
}
else if (((v1 < v2) && (input_value > v2)) || ((v1 > v2) && (input_value < v2)))
{
*left_idx = *right_idx = end;
res = kKitResult_OutRange;
}
else
{
*left_idx = 0;
*right_idx = 1;
for (i = 0; i < end; i++)
{
kit_table_get_data(item, i, &v1);
kit_table_get_data(item, i + 1, &v2);
if ((input_value >= v1 && input_value <= v2) || (input_value <= v1 && input_value >= v2))
{
*left_idx = i;
*right_idx = i + 1;
break;
}
}
res = kKitResult_Ok;
}
}
}
return res;
}
KitResult kit_table_linear_search(TwoDTabItem *item, int32_t input_value, uint32_t factor, int32_t *output_value)
{
KitResult res = kKitResult_ParamErr;
uint8_t left_idx, right_idx;
int32_t dat_x, dat_y, x_left_value, x_right_value, y_left_value, y_right_value;
*output_value = 0;
if ((item != NULL) && (item->x.tab != NULL) && (item->y.tab != NULL))
{
res = kit_table_search_index(&item->x, input_value, &left_idx, &right_idx);
kit_table_get_data(&item->y, left_idx, &y_left_value);
kit_table_get_data(&item->y, right_idx, &y_right_value);
if((res == kKitResult_OutRange) || (y_left_value == y_right_value))
{
*output_value = y_left_value * factor;
}
else
{
kit_table_get_data(&item->y, left_idx, &y_left_value);
kit_table_get_data(&item->y, right_idx, &y_right_value);
kit_table_get_data(&item->x, left_idx, &x_left_value);
kit_table_get_data(&item->x, right_idx, &x_right_value);
dat_x = x_right_value - x_left_value;
dat_y = y_right_value - y_left_value;
*output_value = ((int64_t)dat_y * factor * ((int32_t)input_value - x_left_value) / dat_x) + y_left_value * factor;
res = kKitResult_Ok;
}
}
return res;
}
KitResult kit_table_bilinear_search(ThreeDTabItem *item, int32_t x_input, int32_t y_input, int32_t *z_output)
{
KitResult res = kKitResult_Ok;
uint8_t x_left_idx, x_right_idx, y_left_idx, y_right_idx;
int32_t data_x1_y1, data_x1_y2, data_x2_y1, data_x2_y2;
int32_t x1, x2, y1, y2, dat_x;
res &= kit_table_search_index(&item->x, x_input, &x_left_idx, &x_right_idx);
res &= kit_table_search_index(&item->y, y_input, &y_left_idx, &y_right_idx);
if (res == kKitResult_Ok)
{
kit_table_get_data(&item->z, item->x.len * y_left_idx + x_left_idx, &data_x1_y1);
kit_table_get_data(&item->z, item->x.len * y_right_idx + x_left_idx, &data_x1_y2);
kit_table_get_data(&item->z, item->x.len * y_left_idx + x_right_idx, &data_x2_y1);
kit_table_get_data(&item->z, item->x.len * y_right_idx + x_right_idx, &data_x2_y2);
kit_table_get_data(&item->x, x_left_idx, &x1);
kit_table_get_data(&item->x, x_right_idx, &x2);
kit_table_get_data(&item->y, y_left_idx, &y1);
kit_table_get_data(&item->y, y_right_idx, &y2);
dat_x = (x2 - x1) * (y2 - y1);
*z_output = data_x1_y1 * (x2 - (int32_t)x_input) * (y2 - (int32_t)y_input) + data_x2_y1 * ((int32_t)x_input - x1) * (y2 - (int32_t)y_input)
+ data_x1_y2 * (x2 - (int32_t)x_input) * ((int32_t)y_input - y1) + data_x2_y2 * ((int32_t)x_input - x1) * ((int32_t)y_input - y1);
*z_output = (*z_output + (dat_x >> 1)) / dat_x;
}
return res;
}
KitResult kit_table_bilinear_search_by_yz(ThreeDTabItem* item, int32_t y_input, int32_t z_input, uint32_t factor, int32_t* x_output)
{
KitResult res = kKitResult_ParamErr;
uint8_t y_left_idx, y_right_idx, value[200];
int32_t i, tmp, dat_x, dat_y;
int32_t x_left_value, x_right_value, y_left_value, y_right_value;
TwoDTabItem table;
if (item != NULL)
{
res = kit_table_search_index(&item->y, y_input, &y_left_idx, &y_right_idx);
if ((res == kKitResult_Ok) || (res == kKitResult_OutRange))
{
//创建二维表x轴数据为拟合出来新数据y轴为原来三维表的x轴数据
table.x.len = item->x.len;
table.x.tab = (uint8_t*)value;
table.x.type = item->z.type;
table.y.len = item->x.len;
table.y.tab = item->x.tab;
table.y.type = item->x.type;
kit_table_get_data(&item->y, y_left_idx, &y_left_value);
kit_table_get_data(&item->y, y_right_idx, &y_right_value);
dat_x = y_input - y_left_value;
//数据不用插值,直接取
if ((dat_x == 0) || (res == kKitResult_OutRange))
{
for (i = 0; i < item->x.len; i++)
{
kit_table_get_data(&item->z, item->x.len * y_left_idx + i, &x_left_value);
kit_table_set_data(&table.x, i, x_left_value);
}
}
//数据不用插值,直接取
else if (y_input == y_right_value)
{
for (i = 0; i < item->x.len; i++)
{
kit_table_get_data(&item->z, item->x.len * y_right_idx + i, &x_left_value);
kit_table_set_data(&table.x, i, x_left_value);
}
}
else
{
dat_y = y_right_value - y_left_value;
for (i = 0; i < item->x.len; i++)
{
kit_table_get_data(&item->z, item->x.len * y_left_idx + i, &x_left_value);
kit_table_get_data(&item->z, item->x.len * y_right_idx + i, &x_right_value);
tmp = (x_right_value - x_left_value) * dat_x / dat_y + x_left_value;
kit_table_set_data(&table.x, i, tmp);
}
}
res = kit_table_linear_search(&table, z_input, factor, x_output);
}
}
return res;
}