请帮忙看看是哪里的逻辑有问题? (倒传递类神经)
#include <stdio.h>#include <conio.h>
#include <float.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <8254.h>
#include <io.h>
#include <alloc.h>
#include <math.h>
#include <ADDA.h>
#include "PCI.C"
// Global variable declare
dword gdwBaseAddr; //Base address
int giIrqNum;
// Local fucntion declare
word wVendorId, wDeviceId, wIndex;
int iErrCode;
byte ucBusNumber, ucDevAndFunc;
dword dwData;
int iChannel,iPortAddr;
word wRawData;
float fVoltage, fHiVolt, fLoVolt;
byte ucRegVal;
#define base833 0x200 /* PCL-833 address 0x200 */
#define TICK 0x1c
#define MAXFREQ 10026
#define MINFREQ 19
#define pi 3.1415926
#define Ninp 1
#define Nout 1
#define Nhid 5
double eta=0.01; // 學習速率
double alpha=0.05; // 慣性因子
double lumda=0.25;
void interrupt (*old)(void); // interrupt old address // /*中斷空間(副程式宣告)*/
void interrupt controller(void); // interrupt control // /*中斷空間(控制器副程式宣告)*/
void changtimer(float); // 改變時脈 for real time control //
float Encoder(void); //
void Ini833(void);
void End(void); // 結束 //
void tracking_function();
void update_weight(void);
void neuro_out(void);
void calculate_function(char);
void data_num();
void tracking();
void read_weight();
void mem();
void save_data();
float far *data_x;
float far *xd;
float far *Vx;
float A,fs,T,t,k; //A=amplitude,fs=frequency,T=finish time,t=period time //
int inter,n,nc_num;
float fs,amp,out,desired;
float error,dat;
float dist,u;
double X[Ninp],H[Nhid],Y[Nout];
double far *W_xh,far *W_hy;
double far *Theta_h,far *Theta_y;
double delta_h[Nhid],delta_y[Nout];
double dTheta_h[Nhid],dTheta_y[Nout];
double dW_xh[Nhid],dW_hy[Nhid];
double sumun,expneta,expnetb;
unsigned long free_mem;
long int f=0,inc;
char kind,type;
FILE *fp,*fp1,*fp3,*fap,*fip,*fop,*fin;
void interrupt controller(void)
{
dist=-Encoder ()*2/100000; //光學尺讀的位移
data_x[inter]=dist;
dat=data_x[inter];
error=xd[inter%nc_num]-dat; //error
X[0]=xd[inter]; //position
neuro_out();
update_weight(); //update_weight
//**wight值回存到第一行**//
Theta_y[inter]=Theta_y[0];
for(k=0;k<Nhid;k++)
{
W_xh[inter*Nhid+k]=W_xh[k];
W_hy[inter*Nhid+k]=W_hy[k];
Theta_h[inter*Nhid+k]=Theta_h[k];
}
u=Y[0]*5.0; //控制輸出
out=u; //實際輸出電壓
Vx[inter]=u;
//****保護程式電壓***//
if (out>=5)
{
wRawData = ( word )((5+5) * (65535/10));
outport( gdwBaseAddr + iPortAddr, wRawData );
}
else if (out<=-5)
{
wRawData = ( word )((-5+5) * (65535/10));
outport( gdwBaseAddr + iPortAddr, wRawData );
}
else
{
wRawData = ( word )((out+5) * (65535/10));
outport( gdwBaseAddr + iPortAddr, wRawData );
}
inter++;
}
main()
{
start:
clrscr();
gotoxy(15,5);printf(" What kinds of model do you control ?\n ");
gotoxy(15,6);printf("**************************************\n");
//gotoxy(15,7);printf(" (1) : return to origin \n");
gotoxy(15,8);printf(" (1) : tracking function \n");
gotoxy(15,9);printf(" (2) : Quit \n");
gotoxy(15,10);printf("Please select : ");
scanf("%c",&kind);
switch(kind)
{
case '1':
tracking_function();
break;
case '2':
goto end;
default:
goto start;
}
end:
farfree(data_x);
farfree(xd);
farfree(Vx);
farfree(Theta_y);
farfree(Theta_h);
farfree(W_xh);
farfree(W_hy);
End();
}
void tracking_function()
{
wVendorId = 0x13fe;
wDeviceId = 0x1716;
wIndex = 0;
clrscr();
gotoxy( 10, 5 );
printf( "----------------- PCI-1716 AOSOFT.C -----------------------" );
//==========================================================================
// Get 1716's resource
//==========================================================================
//
// Search PCI-1716
//
iErrCode = find_pci_device(
wDeviceId,
wVendorId,
wIndex,
&ucBusNumber,
&ucDevAndFunc );
if ( iErrCode == NOT_SUCCESSFUL )
{
printf( "\n\tPCI-1716 search fail.\n" );
exit( 1 );
}
//************************************************
//Get base address, from PCI base address range 2
//************************************************
iErrCode = read_configuration_dword(
ucBusNumber,
ucDevAndFunc,
PCI_CS_BASE_ADDRESS_2,
&dwData );
if ( iErrCode == NOT_SUCCESSFUL )
{
printf( "\n\tPCI-1716 gets base address fail.\n" );
exit( 1 );
}
else
{
gdwBaseAddr = dwData & 0xfffffffc;
}
//**************************************
//Get Interrupt line
//**************************************
iErrCode = read_configuration_dword(
ucBusNumber,
ucDevAndFunc,
PCI_CS_INTERRUPT_LINE,
&dwData );
if ( iErrCode == NOT_SUCCESSFUL )
{
printf( "\n\tPCI-1716 gets interrupt line fail.\n" );
exit( 1 );
}
else
{
giIrqNum = dwData & 0xf;
}
iChannel=0;
ucRegVal = 0x0; //Internal reference, reference voltage 5V
outportb( gdwBaseAddr + 14 + iChannel, ucRegVal );
iPortAddr = 10 + iChannel * 2; //11 for DA0 port offset, 13 for DA1
/**************************************************************************
* Wrivte voltage out
*************************************************************************/
//wRawData = ( word )( fVoltage / ( fHiVolt - fLoVolt ) * 0xffff );
wRawData = ( word )((0.0+5) * (65535/10));
outport( gdwBaseAddr + iPortAddr, wRawData );
start1:
clrscr();
gotoxy(15,5);printf(" What kinds of model do you control ?\n ");
gotoxy(15,6);printf("**************************************\n");
gotoxy(15,7);printf(" (1) : tracking step function \n");
gotoxy(15,8);printf(" (2) : tracking sine function \n");
gotoxy(15,9);printf(" (3) : tracking square function \n");
gotoxy(15,10);printf(" (4) : tracking triangular function \n");
gotoxy(15,11);printf(" (5) : tracking line function \n");
gotoxy(15,12);printf(" (6) : Quit \n");
gotoxy(15,13);printf("Please select : ");
scanf("%c",&type);
switch(type)
{
case '1': break;
case '2': break;
case '3': break;
case '4': break;
case '5': break;
case '6':
goto end1;
default:
goto start1;
}
data_num();
calculate_function(type);
read_weight();
tracking();
farfree(data_x);
farfree(xd);
farfree(Vx);
farfree(Theta_y);
farfree(Theta_h);
farfree(W_xh);
farfree(W_hy);
end1:
wRawData = ( word )((-0.1+5) * (65535/10));
outport( gdwBaseAddr + iPortAddr, wRawData );
End();
}
void data_num()
{
clrscr();
mem();
gotoxy(1,5);
printf("please input sampling frequency (HZ) ( 19 HZ< fs < 10026 HZ):");
scanf("%f",&fs);
gotoxy(1,6);
printf("please input finishing time T < %d(sec) : ",free_mem/(44*(int)fs));
scanf("%f",&T);
printf("please input tracking period t(sec) : ");
scanf("%f",&t);
printf("please input Amplitude A(mm) : ");
scanf("%f",&A);
n=fs*T;
nc_num=fs*t;
}
void calculate_function(char type)
{
int j;
float sita;
tt:
data_x=(float far *)farcalloc(n,sizeof(float));
xd=(float far *)farcalloc(n,sizeof(float));
Vx=(float far *)farcalloc(n,sizeof(float));
if(((xd==NULL) || (Vx==NULL)) || (data_x==NULL))
{
printf("Memory checking error....");
farfree(data_x);
farfree(xd);
farfree(Vx);
goto tt;
}
tt1:
Theta_y=(double far *)farcalloc(n+5,sizeof(double));
Theta_h=(double far *)farcalloc(n*Nhid+5,sizeof(double));
W_xh=(double far *)farcalloc(n*Nhid+5,sizeof(double));
W_hy=(double far *)farcalloc(n*Nhid+5,sizeof(double));
if((Theta_y==NULL) || (Theta_h==NULL) || (W_xh==NULL) || (W_hy==NULL))
{
printf("Memory checking error....");
farfree(Theta_y);
farfree(Theta_h);
farfree(W_xh);
farfree(W_hy);
goto tt1;
}
if (type=='1') // step
{
for(j=0;j<=nc_num;j++)
xd[j]=A; //A=amplitude
}
else if(type=='2') // sin wave
{
for(j=0;j<=nc_num;j++)
{
sita=2*pi/(float)nc_num*j;
xd[j]=A*(float)sin((double)sita);
}
}
else if(type=='3') // square wave
{
for(j=0;j<=nc_num;j++)
{
if(j<=nc_num/2)
xd[j]=A;
else
xd[j]=-A;
}
}
else if(type=='4') //
{
for(j=0;j<=nc_num;j++)
{
if(j<=nc_num/4)
xd[j]=A*4.0/nc_num*j;
else if((j>nc_num/4) && (j<=nc_num*3/4))
xd[j]=A-4.0*A/(float)nc_num*(j-nc_num/4.0);
else
xd[j]=-A+4.0*A/(float)nc_num*(j-nc_num*3/4.0);
}
}
else
{
for(j=0;j<=n;j++)
xd[j]=(float)A*(float)j/(float)n;
}
}
void tracking()
{
int j,i;
gotoxy(15,15);printf(" The vlotage is now! ");
gotoxy(15,16);printf(" Error");
gotoxy(15,17);printf(" Postion is ");
changtimer(fs);
Ini833();
old=getvect(0x1c); //儲存卡片原本厔置設定
setvect(0x1c,controller); //中斷到控制器副程式
for(i=0;i<=n;i++)
while(inter<=n)
{
gotoxy(32,15);printf("%3.6f",out);
gotoxy(32,16);printf("%f",xd[inter%nc_num]-dat);
gotoxy(32,17);printf("%f",dat);
}
for(j=0;j<=2;j++)
setvect(TICK,old); //回到卡片原本設定位置
changtimer(18.2);//outportb(TIME0,0); //回到卡片原本設定時脈18.2
printf("\a");
save_data();
}
void save_data()
{
int j,h,k;
if(type=='1')
{
fp=fopen("c:\\data\\step_x.dat","w");
for (j=0;j<=n;j++)
fprintf(fp,"%f %f %f %f %f\n",xd[j%nc_num],T/n*j,Vx[j],data_x[j],data_x[j]-xd[j%nc_num]);
}
else if(type=='2')
{
fp=fopen("c:\\data\\sine_x.dat","w");
for (j=0;j<=n;j++)
fprintf(fp,"%f %f %f %f %f\n",xd[j%nc_num],T/n*j,Vx[j],data_x[j],sumun);
}
else if(type=='3')
{
fp=fopen("c:\\data\\squa_x.dat","w");
for (j=0;j<=n;j++)
fprintf(fp,"%f %f %f %f \n",xd[j%nc_num],T/n*j,Vx[j],data_x[j]);
}
else if(type=='4')
{
fp=fopen("c:\\data\\tria_x.dat","w");
for (j=0;j<=n;j++)
fprintf(fp,"%f %f %f %f\n",xd[j%nc_num],T/n*j,Vx[j],data_x[j]);
}
else if(type=='5')
{
fp=fopen("c:\\data\\line_x.dat","w");
for (j=0;j<=n;j++)
fprintf(fp,"%f %f %f %f\n",xd[j],T/n*j,Vx[j],data_x[j]);
}
fclose(fp);
/******** save weight W_xh,W_hy,Theta_h ********/
if(type=='1')
fp3=fopen("c:\\data\\W_step_x.dat","w");
else if(type=='2')
fp3=fopen("c:\\data\\W_sine_x.dat","w");
else if(type=='3')
fp3=fopen("c:\\data\\W_squa_x.dat","w");
else if(type=='4')
fp3=fopen("c:\\data\\W_tria_x.dat","w");
else if(type=='5')
fp3=fopen("c:\\data\\W_line_x.dat","w");
else
exit(1);
for(k=0;k<=n;k++)
{
for(h=0;h<Nhid;h++)
fprintf(fp3,"%f ",W_xh[k*Nhid+h]);
for(h=0;h<Nhid;h++)
fprintf(fp3,"%f ",W_hy[k*Nhid+h]);
for(h=0;h<Nhid;h++)
fprintf(fp3,"%f ",Theta_h[k*Nhid+h]);
fprintf(fp3,"%f \n",Theta_y[k]);
}
fclose(fp3);
}
void changtimer(float fs) // change timer //
{
long int counter;
unsigned tim_lb,tim_hb;
if(fs > MAXFREQ) fs = MAXFREQ; // Set upper bound and lower bound
if(fs < MINFREQ) fs = MINFREQ; // of sampling frequency
counter = (int)(1193200L/ fs) ; /* max. freq. of system clock 1.1932 MHz */
tim_hb = counter >> 8; /* setting timer */
tim_lb = counter - (tim_hb << 8);
outportb(TIMECW,IOTIME);
outportb(TIME0,tim_lb);
outportb(TIME0,tim_hb);
}
void mem()
{
free_mem=farcoreleft();
clrscr();
gotoxy(15,1);printf(" The total free memery is %lu bytes\n ",free_mem);
gotoxy(15,2);printf(" So the T*fs must less than %lu", free_mem/44);
}
void End(void)
{
int j;
gotoxy(1,19);printf("Press any key to shut down the system");
getch();
gotoxy(1,20);printf("Wait,Shut down the system....");
Ini833();
//--------------------------------------------------------------
}
void read_weight()
{
int h,k;
double data;
if(type=='1')
fp1=fopen("c:\\data\\W_step_x.dat","r");
else if(type=='2')
fp1=fopen("c:\\data\\W_sine_x.dat","r");
else if(type=='3')
fp1=fopen("c:\\data\\W_squa_x.dat","r");
else if(type=='4')
fp1=fopen("c:\\data\\W_tria_x.dat","r");
else if(type=='5')
fp1=fopen("c:\\data\\W_line_x.dat","r");
else
exit(1);
fseek(fp1,0,0);
for(k=0;k<=n;k++)
{
for(h=0;h<Nhid;h++) /**read W_xh**/
{
fscanf(fp1,"%lf",&data);
W_xh[k*Nhid+h]=data;
}
for(h=0;h<Nhid;h++) /**read W_hy**/
{
fscanf(fp1,"%lf",&data);
W_hy[k*Nhid+h]=data;
}
for(h=0;h<Nhid;h++) /**read Theta_h**/
{
fscanf(fp1,"%lf",&data);
Theta_h[k*Nhid+h]=data;
}
for(h=0;h<Nout;h++) /**read Theta_y**/
{
fscanf(fp1,"%lf\n",&data);
Theta_y[k]=data;
}
}
printf("please check reseting light and hit any key to tracking......");
getch();
}
void Ini833(void)
{
outportb(base833+0,11); /* CH1 Quadrature X4 & reset 800000*/
outportb(base833+3,0); /* CH1 S/W Latched */
outportb(base833+6,0x07); /* CH1 Locked the counter when overflow */
outportb(base833+7,0x07); /* CH1 Reset correspond counter */
outportb(base833+8,0); /* CH1 clock 8MHz and no cascade */
outportb(base833+9,1);
outportb(base833+10,0);
}
float Encoder(void)
{
long int encoder=0,encoder1=0,encoder2=0;
encoder1=inportb(base833+2);encoder1=encoder1<<8;
encoder1|=inportb(base833+1);encoder1=encoder1<<8;
encoder1|=inportb(base833+0);
encoder2=inportb(base833+2);encoder2=encoder2<<8;
encoder2|=inportb(base833+1);encoder2=encoder2<<8;
encoder2|=inportb(base833+0);
encoder =inportb(base833+2); encoder=encoder<<8;
encoder |=inportb(base833+1);encoder=encoder<<8;
encoder |=inportb(base833+0);
if(encoder!=encoder2)
{
encoder=encoder1;
}
encoder=(encoder-0x800000L);
return ((float) encoder);
}
void update_weight()
{
int j,h;
double a;
/**compute delta**/
for(j=0;j<Nout;j++)
delta_y[j]=error;
for(h=0;h<Nhid;h++)
{
a=W_hy[h]*delta_y[0];
//delta_h[h]=0.5*lumda*(1+H[h])*(1-H[h])*a;
delta_h[h]=(1.0-(H[h]*H[h]))*a;
}
/**compute dW**/
for(h=0;h<Nhid;h++)
dW_hy[h]=eta*delta_y[0]*H[h]+alpha*dW_hy[h];
for(j=0;j<Nout;j++)
dTheta_y[j]=-eta*delta_y[j]+alpha*dTheta_y[j];
for(h=0;h<Nhid;h++)
dW_xh[h]=eta*delta_h[h]*X[0]+alpha*dW_xh[h];
for(h=0;h<Nhid;h++)
dTheta_h[h]=-eta*delta_h[h]+alpha*dTheta_h[h];
/**compute W**/
for(h=0;h<Nhid;h++)
W_hy[h]=W_hy[h]+dW_hy[h];
for(j=0;j<Nout;j++)
Theta_y[j]=Theta_y[j]+dTheta_y[j];
for(h=0;h<Nhid;h++)
W_xh[h]=W_xh[h]+dW_xh[h];
for(h=0;h<Nhid;h++)
Theta_h[h]=Theta_h[h]+dTheta_h[h];
}
void neuro_out()
{
int h;
double a,sum,net,net1;
double sum1;
/**Compute output of input-hidden layer**/
sum1=0.0;
for(h=0;h<Nhid;h++)
{
a=X[0]*W_xh[inter*Nhid+h];
//H[h]=(2.0/(1+exp(-lumda*(a-Theta_h[inter*Nhid+h]))))-1.0;
sum1=sum1+X[0]*W_xh[inter*Nhid+h];
net1=sum1-Theta_h[inter*Nhid+h];
expneta=1-exp(-net1);
expnetb=1+exp(-net1);
H[h]=expneta/expnetb;
}
/**Compute output of hidden-output layer**/
sum=0.0;
for(h=0;h<Nhid;h++)
sum=sum+(H[h]*W_hy[inter*Nhid+h]);
net=sum-Theta_y[inter];
sumun=sum;
Y[0]=(1-exp(-(net)))/(1+exp(-(net)));//sum-Theta_y[inter];
}