Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 06:53 14 May 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : CFunction - 2D-table lookup

Author Message
MolsonB
Regular Member

Joined: 25/01/2015
Location: Canada
Posts: 48
Posted: 12:14am 29 Aug 2015
Copy link to clipboard 
Print this post

I'm trying to create a CFunction that will look up a value in a 2D table, using bilinear interpolation. If I have table with data points at p1-p4, but I want to get the value inbetween the numbers.


p2 p4
x----x
| o |
x----x
p1 p3


I'm getting stuck on a silly part with decimals on my ZZ calculation. I'm getting the "weight" of where my datapoint is compared to its axis, in the example above, I'm more bais/weighted towards p3 and p4. Using variable xx/yy in my code, which will hold a float value between 0 to 1.

MPLAB just stops while debugging the calculating of zz. "Unknown error while attempting to unwind callstack! User program stopped"

The answer ZZ = 7





If you see of ways to do this faster, let me know. I was it written out to step through the program easier.

int intrp_2D(unsigned int xData, int yData, unsigned char xCols, unsigned char yRows, unsigned int *xTbl, int *yTbl, int *zTbl) {

unsigned int k, xCol1, xCol2;
int yRow1, yRow2;
float p1, p2, p3, p4, xx, yy, zz;

//Find x-axis
for (k=0; k < xCols; k++) {
if (xTbl[k] == xData) {
xCol1 = k;
xCol2 = k;
xx = 1;
break;
}
else if (xTbl[k] > xData) {
xCol1 = k-1;
xCol2 = k;
//Find weight of X
xx = (xData - xTbl[xCol1]) / (float)(xTbl[xCol2] - xTbl[xCol1]);
break;
}
}

//Find y-axis
for (k=0; k < yRows; k++) {
if (yTbl[k] == yData) {
yRow1 = k;
yRow2 = k;
yy = 1;
break;
}
else if (yTbl[k] > yData) {
yRow1 = k-1;
yRow2 = k;
//Find weight of Y
yy = (yData - yTbl[yRow1]) / (float)(yTbl[yRow2] - yTbl[yRow1]);
break;
}
}
//zd is pointer that just points to the very first array address spot. Have to know # of rows
p1 = *(zTbl + (yRow1*yRows)+xCol1);
p2 = *(zTbl + (yRow2*yRows)+xCol1);
p3 = *(zTbl + (yRow1*yRows)+xCol2);
p4 = *(zTbl + (yRow2*yRows)+xCol2);

zz = (1 - xx) * ((1 - yy) * p1 + yy * p2) + xx * ((1 - yy) * p3 + yy * p4);

return zz;
}

MkII 44pin - v5.0

ColorMax 2 - v4.5
 
MolsonB
Regular Member

Joined: 25/01/2015
Location: Canada
Posts: 48
Posted: 10:55am 29 Aug 2015
Copy link to clipboard 
Print this post

Weird, must be a bug in MPLAB. If I don't 'step by step' debug through the math and just let it run, it won't come back with an error.

How does the interpolation look? See any improvements for speed? Once I learn more about assembly code, I'll see how the compiler optimizes this code.
MkII 44pin - v5.0

ColorMax 2 - v4.5
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8601
Posted: 11:18am 29 Aug 2015
Copy link to clipboard 
Print this post

I suggest you PM G8JCF on the MPLAB stuff. My assumption has always been that you can't debug CFunctions other than the old fashioned route with "print" statements because of the way they are loaded into memory and the way on MIPS they are pseudo relocatable code. I've never tried to debug using MPAB, I just assumed it wouldn't work.

The big issue is that you can't do floating arithmetic in CFunctions this way. There are a set of function calls FAdd, FSub, FMul, FDiv, FCmp that you have to use as the normal operators call library functions that are not relocatable. You also need an include file. I will publish something ASAP

see attached example:


#define FAM
#include "APIDefs.h"
long long fbezier (float *x0, float *y0, float *x1, float *y1,float *x2, float *y2, float *x3, float *y3, long long *colour)
{
float tmp,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6,tmp7,tmp8,t,xt,yt;
int xti,yti,xtlast=-1, ytlast=-1;
int i;
t = 0x0;
for (i=0;i<500;i++)
{
tmp =FSub(M_1,t);
tmp3=FMul(t,t);
tmp4=FMul(tmp,tmp);
tmp1=FMul(tmp3,t);
tmp2=FMul(tmp4,tmp);
tmp5=FMul(M_3, t);
tmp6=FMul(M_3, tmp3);
tmp7=FMul(tmp5,tmp4);
tmp8=FMul(tmp6,tmp);
xt = FAdd(FAdd(FAdd(FMul(tmp2 , *x0) ,
FMul(tmp7 , *x1)) ,
FMul(tmp8 , *x2)) ,
FMul(tmp1 , *x3));

yt = FAdd(FAdd(FAdd(FMul(tmp2 ,*y0) ,
FMul(tmp7 , *y1)) ,
FMul(tmp8 , *y2)) ,
FMul(tmp1 , *y3));
xti=FloatToInt(xt);
yti=FloatToInt(yt);
if((xti!=xtlast) || (yti!=ytlast)) {
DrawPixel(xti, yti, *colour);
xtlast=xti;
ytlast=yti;
}
t=FAdd(t,M_ANY(0x3B03126F));
}
return 0;
}
long long WideBlackLine(long long *xx0, long long *yy0, long long *xx1, long long *yy1, long long *wwd, long long *ffc, long long *bbc, long long *max, long long *min)
{ /* plot an anti-aliased line of width wd */
union utype{
int b;
unsigned char a[4];
}fc,bc,pc;
char cr=10,lf=13,ca[14];

int a,i;
*max=0;
*min=1000;
fc.b=*ffc; bc.b=*bbc;
int x0=*xx0,y0=*yy0,x1=*xx1,y1=*yy1;
float wd=IntToFloat(*wwd);
int dx = abs(x1-x0), sx = x0 < x1 ? 1 : -1;
int dy = abs(y1-y0), sy = y0 < y1 ? 1 : -1;
int err = dx-dy, e2, x2, y2; /* error value e_xy */

float ed = dx+dy==0 ? IntToFloat(1) : FSqrt((FAdd(IntToFloat(dx*dx),IntToFloat(dy*dy))));

for ( wd = FDiv(FAdd(wd,IntToFloat(1)),IntToFloat(2)); ; ) { // pixel loop
if(fc.b!=bc.b){
a=lmax(0,FloatToInt(FMul(IntToFloat(255),FSub(FAdd(FDiv(IntToFloat(abs(err-dx+dy)),ed),IntToFloat(1)) , wd))));
if(fc.a[0]==255)pc.a[0]=a;
if(fc.a[1]==255)pc.a[1]=lmin(a+4,255);
if(fc.a[2]==255)pc.a[2]=a;
}
DrawPixel(x0, y0, pc.b);
e2 = err; x2 = x0;
if (2*e2 >= -dx) { // x step
for (e2 += dy, y2 = y0; (FCmp(IntToFloat(e2),(FMul(ed,wd)))==-1) && (y1 != y2 || dx > dy); e2 += dx){
y2 += sy;
if(fc.b!=bc.b){
a=lmax(0,FloatToInt(FMul(IntToFloat(255),FSub(FAdd(FDiv(IntToFloat(abs(e2)),ed),IntToFloat(1)) , wd))));
if(fc.a[0]==255)pc.a[0]=a;
if(fc.a[1]==255)pc.a[1]=lmin(a+4,255);
if(fc.a[2]==255)pc.a[2]=a;
} else pc.b=fc.b;
DrawPixel(x0, y2, pc.b);
}
if (x0 == x1) break;
e2 = err; err -= dy; x0 += sx;
}
if (2*e2 <= dy) { // y step
for (e2 = dx-e2; (FCmp(IntToFloat(e2),(FMul(ed,wd)))==-1) && (x1 != x2 || dx < dy); e2 += dy){
x2 += sx;
if(fc.b!=bc.b){
if(a<*min)*min=a;
if(a>*max)*max=a;
IntToStr(ca,a,10);
for(i=0;i<14;i++){
if(ca==0) break;
}
ca=cr;
ca[i+1]=lf;
ca[i+2]=0;
MMPrintString(ca);
a=lmax(0,FloatToInt(FMul(IntToFloat(255),FSub(FAdd(FDiv(IntToFloat(abs(e2)),ed),IntToFloat(1)) , wd))));
if(fc.a[0]==255)pc.a[0]=a;
if(fc.a[1]==255)pc.a[1]=lmin(a+4,255);
if(fc.a[2]==255)pc.a[2]=a;
} else pc.b=fc.b;
DrawPixel(x2, y0, pc.b);
}
if (y0 == y1) break;
err += dx; y0 += sy;
}
}
return 0;
}
Edited by matherp 2015-09-03
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024