📄 ftankvolume.c
字号:
#include "ftankvolume.h"
VolumeCfg CONFIGUATIONS; // configuations
BYTE TANKVOLUME_BUFFER[FVOL_TANKBUFFER_SIZE]; // tank volume-table buffer. 50k
/* get configurations */
Boolean fvol_getConfig(CHAR* filename, VolumeCfg* cfg)
{
REGINT i,size,offset;
DBG_MSG("get configuration..\n");
// open & get the number of tanks
//if ((cfg->fd = open (filename, O_RDONLY|O_BINARY)) < 0)
if ((cfg->fd = open (filename, O_RDONLY)) < 0)
{
DBG_MSG2("open file '%s' failed\n", filename);
return False;
}
if(f_SeekRead(cfg->fd, &cfg->u8TankNum, 0, 1) != 1)
return False;
if(cfg->u8TankNum > MAX_TANK_NUM)
{
DBG_MSG("tank number overrange error.\n");
return False;
}
// parase tanks
offset = 1;
for(i=0; i<cfg->u8TankNum; i++)
{
size = sizeof(cfg->_cfgFiles[i]);
if(f_SeekRead(cfg->fd, cfg->_cfgFiles[i], offset+i*size, size) != size)
return False;
cfg->cfgFiles[i] = cfg->_cfgFiles[i];
}
close(cfg->fd);
DBG_MSG("configed successfully\n");
return True;
}
Boolean fvol_init(CHAR* cfgFileName)
{
Boolean re = False;
VolumeCfg* cnf = &CONFIGUATIONS;
DBG_MSG("init..\n");
// get configuations
if( fvol_getConfig(cfgFileName, cnf) == False)
{
close(cnf->fd);
return False;
}
DBG_MSG("init finished\n");
return True;
}
Boolean fvol_bufferVolumeTable(VolumeTable* table, REGINT fd, INT32 offset, BYTE* buffer, INT32* usedsize)
{
INT32 bufsize;
UINT16 itemNum;
VolumeTableType type;
*usedsize = 0;
type = table->Type;
if(f_SeekRead(fd, &itemNum, offset, 2) != 2)
return False;
switch(type)
{
case Index:
bufsize = 8 * itemNum;
break;
case Ratable0:
bufsize = 80 * itemNum;
break;
default:
return False;
}
if(f_SeekRead(fd, buffer, offset, bufsize) != bufsize)
return False;
table->u16ItemNum = itemNum;
*usedsize = bufsize;
return True;
}
Boolean fvol_bufferTankdata(TankVolCfg* tank, INT32 tankIndex)
{
REGINT size,offset,bufcount;
UINT32 usize;
struct stat sb;
DBG_MSG2("tank index: %d\n", tankIndex);
DBG_MSG("init tank data..\n");
// --- open ---
//if ((tank->fd = open (CONFIGUATIONS.cfgFiles[tankIndex], O_RDONLY|O_BINARY)) < 0)
if ((tank->fd = open (CONFIGUATIONS.cfgFiles[tankIndex], O_RDONLY)) < 0)
{
DBG_MSG2("open configuration file '%s' failed\n", CONFIGUATIONS.cfgFiles[tankIndex]);
return False;
}
fstat(tank->fd, &sb);
if(sb.st_size > FVOL_TANKBUFFER_SIZE)
{
DBG_MSG3("tank cfgfile %s is too big, %d bytes limit\n", CONFIGUATIONS.cfgFiles[tankIndex], FVOL_TANKBUFFER_SIZE);
return False;
}
// --- get tank info---
DBG_MSG("tank coefficients.. \n");
offset = 0;
size = sizeof(tank->Name);
if(f_SeekRead(tank->fd, tank->Name, offset, size) != size)
{
return False;
}
offset = 20;
if(f_SeekRead(tank->fd, &tank->DM_TABLE.n32Offset, offset, 4) != 4)
return False;
if(f_SeekRead(tank->fd, &tank->MM_TABLE.n32Offset, offset+4, 4) != 4)
return False;
if(f_SeekRead(tank->fd, &tank->AMEND_TABLE.n32Offset, offset+8, 4) != 4)
return False;
if(f_SeekRead(tank->fd, &tank->FUND_TABLE.n32Offset,offset+12, 4) != 4)
return False;
// --- buffer volume table ---
DBG_MSG("volume table.. \n");
bufcount = 0;
// DM table
tank->DM_TABLE.Type = Index;
tank->DM_TABLE.u16ItemNum = 0;
if(tank->DM_TABLE.n32Offset > 0)
{
if(fvol_bufferVolumeTable(&tank->DM_TABLE, tank->fd, tank->DM_TABLE.n32Offset, TANKVOLUME_BUFFER + bufcount, &usize) == False)
return False;
tank->DM_TABLE.n32Offset = bufcount;
bufcount += usize;
}
// MM table
tank->MM_TABLE.Type = Ratable0;
tank->MM_TABLE.u16ItemNum = 0;
if(tank->MM_TABLE.n32Offset > 0)
{
if(fvol_bufferVolumeTable(&tank->MM_TABLE, tank->fd, tank->MM_TABLE.n32Offset, TANKVOLUME_BUFFER + bufcount, &usize) == False)
return False;
tank->MM_TABLE.n32Offset = bufcount;
bufcount += usize;
}
// Amend table
tank->AMEND_TABLE.Type = Index;
tank->AMEND_TABLE.u16ItemNum = 0;
if(tank->AMEND_TABLE.n32Offset > 0)
{
if(fvol_bufferVolumeTable(&tank->AMEND_TABLE, tank->fd, tank->AMEND_TABLE.n32Offset, TANKVOLUME_BUFFER + bufcount, &usize) == False)
return False;
tank->AMEND_TABLE.n32Offset = bufcount;
bufcount += usize;
}
// Fund table
tank->FUND_TABLE.Type = Index;
tank->FUND_TABLE.u16ItemNum = 0;
if(tank->FUND_TABLE.n32Offset > 0)
{
if(fvol_bufferVolumeTable(&tank->FUND_TABLE, tank->fd, tank->FUND_TABLE.n32Offset, TANKVOLUME_BUFFER + bufcount, &usize) == False)
return False;
tank->FUND_TABLE.n32Offset = bufcount;
bufcount += usize;
}
close(tank->fd);
DBG_MSG("tank data init ok\n");
return True;
}
INT32 fvol_calVolume(TankVolCfg* tank, TankCoefficient* pTankData)
{
INT32 liquidLevel;
INT32 dmvalue,mmvalue,cval,result;
MatchValue dmdetail, mmdetail;
liquidLevel = pTankData->volParams.n32LiquidLevel.value;
// get m-dm volume
cval = liquidLevel;
if( (dmvalue = fvol_getValue(&tank->DM_TABLE, cval, liquidLevel, False, &dmdetail)) < 0)
{
print("calculate dm value failed\n");
return -1;
}
if(dmdetail.isExactValue == True || (liquidLevel - dmdetail.n32RangeA) > 99)
{
mmvalue = 0;
}
else
{
// get m-dm volume
cval = dmdetail.n32RangeA;
if( (dmvalue = fvol_getValue(&tank->DM_TABLE, cval, liquidLevel, True, &mmdetail)) < 0)
{
print("calculate dm value failed\n");
return -1;
}
// get cm-mm volume
cval = liquidLevel - dmdetail.n32RangeA;
if( (mmvalue = fvol_getValue(&tank->MM_TABLE, cval, liquidLevel, True, &mmdetail)) < 0)
{
print("calculate mm value failed\n");
return -1;
}
}
// get base volume
// get revisory volume
// calculate with tank coefficients
result = dmvalue + mmvalue;
return result;
}
INT32 fvol_getVolume(REGINT tankIndex, TankCoefficient* pTankData)
{
TankVolCfg tank;
if(tankIndex <0 || (tankIndex + 1)>MAX_TANK_NUM)
return -1;
if( !fvol_bufferTankdata(&tank, tankIndex) )
{
close(tank.fd);
return -1;
}
return fvol_calVolume(&tank, pTankData);
}
INT32 fvol_matchIndexVolume(VolumeTable* table, INT32 matchvalue, Boolean matchExactly, MatchValue* detail)
{
REGINT index,i,j;
DOUBLE dtempval;
REGINT theorSearchTimes;
REGINT countSearchTimes;
IndexItem tempIndexItem;
IndexItem tempIndexItem2;
INT32 result = -1;
if(table->u16ItemNum <= 0)
return -1;
else if(matchvalue == 0)
return 0;
else
{
index = 0;
i=0; j = table->u16ItemNum - 1;
countSearchTimes = 0;
theorSearchTimes = table->u16ItemNum/2 + 1;
while(index < table->u16ItemNum)
{
index = (i+j)/2;
if(fvol_GetIndexItem(table, &tempIndexItem, index) )
{
if(matchvalue == tempIndexItem.n32Index)
{
result = tempIndexItem.n32Value;
detail->isExactValue = True;
break;
}
else if(i+1 == j)
{
if(fvol_GetIndexItem(table, &tempIndexItem, i) && fvol_GetIndexItem(table, &tempIndexItem2, j))
{
detail->isExactValue = True;
if(matchvalue == tempIndexItem.n32Index)
result = tempIndexItem.n32Value;
else if(matchvalue == tempIndexItem2.n32Index)
result = tempIndexItem2.n32Value;
else if(matchExactly == True)
{
// do nothing
}
else if(matchvalue>tempIndexItem.n32Index && matchvalue<tempIndexItem2.n32Index)
{
detail->isExactValue = False;
detail->n32RangeA = tempIndexItem.n32Index;
detail->n32RangeB = tempIndexItem2.n32Index;
dtempval = (DOUBLE)(tempIndexItem2.n32Index-tempIndexItem.n32Index);
if(dtempval == 0)
result = (tempIndexItem.n32Value + tempIndexItem2.n32Value)/2;
else
{
dtempval = (DOUBLE)(tempIndexItem2.n32Value-tempIndexItem.n32Value) / dtempval;
result = tempIndexItem.n32Value + dtempval * (matchvalue - tempIndexItem.n32Index);
}
}
}
break;
}
else if(i == j)
break;
else if(matchvalue < tempIndexItem.n32Index)
j = index;
else
i = index;
}
else break;
if(++countSearchTimes > theorSearchTimes)
break;
}
}
if(result == -1)
{
print("can't match index value:%d\n", matchvalue);
}
return result;
}
INT32 fvol_matchRatable0Volume(VolumeTable* table, INT32 matchvalue, INT32 liquidLevel)
{
REGINT index,i,j;
REGINT theorSearchTimes,countSearchTimes;
RatableItem tempRatableItem;
INT32 result;
result = -1;
ASSERT(matchvalue > 99);
if(table->u16ItemNum <= 0)
return -1;
else if(matchvalue == 0)
return 0;
else
{
index = 0;
i=0; j = table->u16ItemNum-1;
countSearchTimes = 0;
theorSearchTimes = table->u16ItemNum/2 + 1;
while(index < table->u16ItemNum)
{
index = (i+j)/2;
if(fvol_GetRatable0Item(table, &tempRatableItem, index) )
{
if(liquidLevel >= tempRatableItem.n32LiquidLevel_Min && liquidLevel<tempRatableItem.n32LiquidLevel_Max)
{
result = 0;
if(matchvalue/10 > 0)
result += tempRatableItem.unitage_cm[matchvalue/10-1];
if(matchvalue%10 > 0)
result += tempRatableItem.unitage_mm[matchvalue%10-1];
break;
}
else if(i == j)
break;
else if(liquidLevel < tempRatableItem.n32LiquidLevel_Min)
j = index - 1;
else
i = index + 1;
}
else break;
if(++countSearchTimes > theorSearchTimes)
break;
}
}
if(result == -1)
{
print("can't match ratable value at liquidlevel %d\n", liquidLevel);
}
return result;
}
INT32 fvol_getValue(VolumeTable* table, INT32 matchvalue, INT32 liquidLevel, Boolean matchExactly, MatchValue* detail)
{
switch(table->Type)
{
case Index:
return fvol_matchIndexVolume(table, matchvalue, matchExactly, detail);
case Ratable0:
return fvol_matchRatable0Volume(table, matchvalue, liquidLevel);
}
return -1;
}
Boolean fvol_GetIndexItem(VolumeTable* table, IndexItem* item, INT32 index)
{
REGINT offset;
ASSERT(index < 0 || index >= table->u16ItemNum);
offset = (REGINT)TANKVOLUME_BUFFER + table->n32Offset + 2;
offset += index*8;
memcpy(&item->n32Index, offset, 4);
memcpy(&item->n32Value, offset + 4, 4);
return True;
}
Boolean fvol_GetRatable0Item(VolumeTable* table, RatableItem* item, INT32 index)
{
REGINT offset,size;
ASSERT(index < 0 || index >= table->u16ItemNum);
offset = TANKVOLUME_BUFFER + table->n32Offset + 2;
offset += index*80;
memcpy(&item->n32LiquidLevel_Min, offset, (size=4) );
offset += size;
memcpy(&item->n32LiquidLevel_Max, offset, (size=4));
offset += size;
memcpy(&item->unitage_cm, offset, (size=36));
offset += size;
memcpy(&item->unitage_mm, offset, (size=36));
return True;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -