366 lines
7.8 KiB
C
366 lines
7.8 KiB
C
#include "mywin_inc.h"
|
|
#include "mywin_user_train.h"
|
|
#include "arm_math.h"
|
|
#include "qmc6310.h"
|
|
#include "math.h"
|
|
|
|
|
|
#define WIN_TRAIN_TYPE "WIN_TrainStruct"
|
|
|
|
|
|
|
|
WIN_TrainStruct *WIN_CreatTrain (WIN_WindowStruct *base,
|
|
void (*msgLoop)(struct _WIN_WindowStruct *win,WIN_MsgStruct *msg),
|
|
int x,int y,int x_size,int y_size)
|
|
{
|
|
//重设消息循环
|
|
if (msgLoop==0)
|
|
{
|
|
msgLoop=(void (*)(struct _WIN_WindowStruct *win,WIN_MsgStruct *msg))TRAIN_DefaultMsgLoop;
|
|
}
|
|
|
|
WIN_TrainStruct *ret=mymalloc (sizeof ( WIN_TrainStruct));
|
|
//调用父类的构造函数
|
|
if (ret)
|
|
{
|
|
mymemset (ret,0,sizeof ( WIN_TrainStruct));
|
|
// if (0==WIN_CreatWindowExt((WIN_WindowStruct *)ret,base,msgLoop,x,y,x_size,y_size))
|
|
if (0==WIN_CreatTouchEx((WIN_TouchWinStruct *)ret,base,msgLoop,x,y,x_size,y_size))
|
|
{
|
|
//创建失败
|
|
myfree (ret);
|
|
ret=0;
|
|
}
|
|
else
|
|
{
|
|
((WIN_WindowStruct *)ret)->winType=WIN_TRAIN_TYPE;
|
|
((WIN_WindowStruct *)ret)->intercept=1;//不发送按键消息到父窗口
|
|
((WIN_WindowStruct *)ret)->color=0xffffff;
|
|
//构造一个
|
|
ret->color1=0xff6600; //橙色
|
|
ret->color2=0x887b6e; //灰白
|
|
ret->timerId= WIN_CreatTimer ((WIN_WindowStruct *)ret,100);
|
|
ret->timer_20ms=WIN_CreatTimer ((WIN_WindowStruct *)ret,20);
|
|
|
|
qmc6310_init();
|
|
ret->fitt_on=1;
|
|
for(int i=0;i<WIN_GET_ARRAY_SIZE(ret->kal);i++)
|
|
{
|
|
kalman_init(&ret->kal[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
//更新数据
|
|
void TRAIN_DataUpdata (WIN_TrainStruct *train,TRAIN_Struct *s)
|
|
{
|
|
//使用内存复制的方法复制结构体
|
|
// mymemcpy (& train->data,s,sizeof (TRAIN_Struct));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//设置背景图片
|
|
void TRAIN_SetBackPic (WIN_TrainStruct *train,WIN_PicStruct *pic)
|
|
{
|
|
WIN_SetBackPic ((WIN_WindowStruct *)train,pic);
|
|
}
|
|
|
|
|
|
//处理按键消息
|
|
int TRAIN_KeyBord (WIN_TrainStruct *train,WIN_KeyStruct *k)
|
|
{
|
|
if (k->shortPress&KEY_VALUE_HOME)
|
|
{
|
|
((WIN_WindowStruct *)train)->deleteWindow((WIN_WindowStruct *)train);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
//由毒素得到文字
|
|
static char *GetTxtByAngle (int angle)
|
|
{
|
|
while (angle<0) angle+=360;
|
|
while (angle>360) angle-=360;
|
|
if ((angle>=360-45/2)||(angle<=45/2))
|
|
{
|
|
return "北";
|
|
}
|
|
else if ((angle>45/2)&&(angle<=45+45/2))
|
|
{
|
|
return "东北";
|
|
}
|
|
else if ((angle>45+45/2)&&(angle<=90+45/2))
|
|
{
|
|
return "东";
|
|
}
|
|
else if ((angle>90+45/2)&&(angle<=135+45/2))
|
|
{
|
|
return "东南";
|
|
}
|
|
else if ((angle>135+45/2)&&(angle<=180+45/2))
|
|
{
|
|
return "南";
|
|
}
|
|
else if ((angle>180+45/2)&&(angle<=225+45/2))
|
|
{
|
|
return "西南";
|
|
}
|
|
else if ((angle>225+45/2)&&(angle<=270+45/2))
|
|
{
|
|
return "西";
|
|
}
|
|
else if ((angle>270+45/2)&&(angle<=315+45/2))
|
|
{
|
|
return "西北";
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//作为指南针的绘制函数
|
|
void TRAIN_CompassPaint (WIN_TrainStruct *train)
|
|
{
|
|
int x=0;
|
|
int y=0;
|
|
int x_size=((WIN_WindowStruct *)train)->x_size;
|
|
int y_size=((WIN_WindowStruct *)train)->y_size;
|
|
|
|
//绘制背景
|
|
WIN_PaintBackGround ((WIN_WindowStruct *)train);
|
|
//显示标题
|
|
int img_x=x+25;
|
|
int img_y=y;
|
|
int img_xsize=0;
|
|
int img_ysize=0;
|
|
int head_ysize=45;
|
|
WIN_SetLcdColor (((WIN_WindowStruct *)train)->color);
|
|
if (train->icon)
|
|
{
|
|
WIN_GetImageSize (train->icon,&img_xsize,&img_ysize);
|
|
if (img_ysize>head_ysize) img_ysize=head_ysize;
|
|
WIN_DrawImagByAlpha (img_x,img_y+head_ysize/2-img_ysize/2, img_xsize,img_ysize,train->icon,WIN_GetLcdColor16());
|
|
img_xsize+=10;
|
|
}
|
|
WIN_DrawTxtAt (train->title,img_x+img_xsize,y+head_ysize/2-WIN_GetFontHight()/2);
|
|
|
|
int r_ex=250/2;
|
|
int r_in=r_ex-10;
|
|
//画外圈
|
|
WIN_SetLcdColor (((WIN_WindowStruct *)train)->color);
|
|
WIN_DrawCircle (x_size/2,y_size/2,r_ex);
|
|
//画刻度
|
|
float angle=train->angle;
|
|
for (int i=0;i<8;i++)
|
|
{
|
|
float sinx=0;
|
|
float cosx=0;
|
|
arm_sin_cos_f32 (angle,&sinx,&cosx);
|
|
angle+=45.0f;
|
|
int x1=x_size/2-sinx*r_ex;
|
|
int y1=y_size/2-cosx*r_ex;
|
|
int x2=x_size/2-sinx*r_in;
|
|
int y2=y_size/2-cosx*r_in;
|
|
WIN_DrawLineAA (x1,y1,x2,y2,4);
|
|
|
|
int x_txt=(x_size/2-sinx*(r_in-WIN_GetFontHight()/2));//-WIN_GetFontHight()/2;
|
|
int y_txt=(y_size/2-cosx*(r_in-WIN_GetFontHight()/2))-WIN_GetFontHight()/2;
|
|
WIN_SetLcdColor (((WIN_WindowStruct *)train)->color);
|
|
if (i==0)//北方
|
|
{
|
|
WIN_SetLcdColor (train->color1);
|
|
WIN_DrawTxtHCenterAt ("N",x_txt,y_txt);
|
|
WIN_SetLcdColor (((WIN_WindowStruct *)train)->color);
|
|
}
|
|
else if (i==2)//西方
|
|
{
|
|
WIN_DrawTxtHCenterAt ("W",x_txt,y_txt);
|
|
}
|
|
else if (i==4)//南方
|
|
{
|
|
WIN_DrawTxtHCenterAt ("S",x_txt,y_txt);
|
|
}
|
|
else if (i==6)//东方
|
|
{
|
|
WIN_DrawTxtHCenterAt ("E",x_txt,y_txt);
|
|
}
|
|
}
|
|
//画箭头
|
|
POINT_Struct point[3]={0};
|
|
point[0].x=x_size/2;
|
|
point[0].y=y_size/2-r_in+18;
|
|
point[1].x=x_size/2-5;
|
|
point[1].y=y_size/2-r_in+23;
|
|
point[2].x=x_size/2+5;
|
|
point[2].y=y_size/2-r_in+23;
|
|
WIN_SetLcdColor (train->color1);
|
|
WIN_FillPolygon (point,3);
|
|
//画内圈
|
|
r_in-=25;
|
|
WIN_DrawCircle (x_size/2,y_size/2,r_in);
|
|
//显示方位
|
|
char txt[20]={0};
|
|
WIN_SetLcdColor (((WIN_WindowStruct *)train)->color);
|
|
WIN_DrawTxtHCenterAt (GetTxtByAngle(train->angle),x_size/2,y_size/2-WIN_GetFontHight());
|
|
sprintf (txt," %.0f°",train->angle);
|
|
WIN_DrawTxtHCenterAt (txt,x_size/2,y_size/2);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//默认绘制函数
|
|
void TRAIN_DefaultPaint (WIN_TrainStruct *train)
|
|
{
|
|
|
|
int x=0;
|
|
int y=0;
|
|
int x_size=((WIN_WindowStruct *)train)->x_size;
|
|
int y_size=((WIN_WindowStruct *)train)->y_size;
|
|
char txt_buff[20]={0};
|
|
int old_font_type=0;
|
|
|
|
//绘制背景
|
|
WIN_PaintBackGround ((WIN_WindowStruct *)train);
|
|
WIN_SetLcdColor (((WIN_WindowStruct *)train)->color);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TRAIN_Refresh(WIN_TrainStruct *axis)
|
|
{
|
|
//椭圆拟合
|
|
if(axis->ell.num>10&&axis->ell.num%10==0)
|
|
{
|
|
if(axis->fitt_on)
|
|
ellipsoid_fitting(&axis->ell);
|
|
}
|
|
|
|
//计算校准后的磁力值
|
|
if(axis->ell.a!=0.0f)
|
|
axis->fitt_raw[0]=(axis->mag_raw[0]-axis->ell.x)/axis->ell.a;
|
|
if(axis->ell.b!=0.0f)
|
|
axis->fitt_raw[1]=(axis->mag_raw[1]-axis->ell.y)/axis->ell.b;
|
|
if(axis->ell.c!=0.0f)
|
|
axis->fitt_raw[2]=(axis->mag_raw[2]-axis->ell.z)/axis->ell.c;
|
|
|
|
//计算模
|
|
axis->mod=sqrtf(axis->fitt_raw[0]*axis->fitt_raw[0]+axis->fitt_raw[1]*axis->fitt_raw[1]+axis->fitt_raw[2]*axis->fitt_raw[2]);
|
|
|
|
//判断是否需要重新校准
|
|
if(axis->mod-1>=-0.1f&&axis->mod-1<=0.1f)
|
|
{
|
|
axis->suss_num++;
|
|
if(axis->suss_num>50) axis->fitt_on=0;
|
|
}
|
|
else
|
|
{
|
|
axis->suss_num=0;
|
|
axis->fitt_on=1;
|
|
}
|
|
|
|
//计算方向
|
|
axis->angle=atan2(axis->fitt_raw[1],axis->fitt_raw[0])*180.0f/3.14159f;
|
|
|
|
//调整90度
|
|
axis->angle+=90.0f;
|
|
if(axis->angle>180.0f) axis->angle-=360.0f;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//默认消息处理函数
|
|
void TRAIN_DefaultMsgLoop (WIN_TrainStruct *train,WIN_MsgStruct *msg)
|
|
{
|
|
WIN_MoveStruct *m=0;
|
|
WIN_TouchStruct *t=0;
|
|
TRAIN_Struct *s=0;
|
|
switch (msg->msg)
|
|
{
|
|
case WIN_MSG_PAINT:
|
|
if(train->paint)
|
|
train->paint(train);
|
|
break;
|
|
case WIN_MSG_TIMER:
|
|
if (msg->data.v==train->timerId)
|
|
{
|
|
TRAIN_Refresh(train);
|
|
WIN_SetInvalidWhenTop ((WIN_WindowStruct *)train);
|
|
}
|
|
else if(msg->data.v==train->timer_20ms)
|
|
{
|
|
qmc6310_read_mag_xyz(train->mag_raw);
|
|
for(int i=0;i<WIN_GET_ARRAY_SIZE(train->kal);i++)
|
|
{
|
|
train->mag_raw[i]=kalman_filter(&train->kal[i],train->mag_raw[i]);
|
|
}
|
|
if(train->fitt_on)
|
|
ellipsoid_add_point(&train->ell,train->mag_raw[0],train->mag_raw[1],train->mag_raw[2]);
|
|
}
|
|
break;
|
|
case WIN_MSG_KEY:
|
|
TRAIN_KeyBord (train,msg->data.p);
|
|
break;
|
|
//状态栏接收的外部消息是为 TRAIN_Struct 类型的结构体
|
|
case WIN_MSG_EXTMSG:
|
|
s=msg->data.p;
|
|
TRAIN_DataUpdata (train,s);
|
|
WIN_SetInvalidWhenTop ((WIN_WindowStruct *)train);
|
|
break;
|
|
default:
|
|
WIN_DefaultMsgLoop((WIN_WindowStruct *)train,msg);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
//#include "res/train.c"
|
|
//#include "res/heart.c"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//进入指南针界面
|
|
WIN_TrainStruct *TRAIN_EnterCompass (WIN_WindowStruct *base)
|
|
{
|
|
WIN_WindowStruct *temp=0;
|
|
temp=(WIN_WindowStruct *)WIN_CreatTrain ((WIN_WindowStruct *)base,0,0,0,((WIN_WindowStruct *)base)->x_size,((WIN_WindowStruct *)base)->y_size);
|
|
WIN_SetBkColor (temp,((WIN_WindowStruct *)base)->bkcolor);
|
|
WIN_SetBackPic (temp,&((WIN_WindowStruct *)base)->pic);
|
|
((WIN_TrainStruct *)temp)->paint=TRAIN_CompassPaint;
|
|
((WIN_TrainStruct *)temp)->title="指南针";
|
|
WIN_ShowWindow (temp);
|
|
return (WIN_TrainStruct *)temp;
|
|
}
|
|
|
|
|
|
|