C/C++实现模糊控制,借助MATLAB辅助设计和fis.c文件
上一篇文章(C /C++語言實現模糊控制)介紹了C/C++中實現模糊控制該怎么做,開始提到的MATLAB模糊控制的C/C++模糊控制接口fis.c庫,不過這個文件有點老,在用VS2010編譯的時候一大堆錯誤,在網上找關于C++中使用 fis.c 的資料,結果一點結果都沒有,說怎么引用fis.c文件,網上的都是說什么頭文件,extern "C"{} 的老一套,問題是fis.c文件中大多數的函數都是static修飾的,不可能自己再做個.h的頭文件,途徑只有一條,用#include "fis.c" 包含這個C語言文件,問題是一包含就是一大堆錯誤,后來看fis.c的代碼發現,原來里面有很多過時的語法,C語言可以編譯,但是C++不可以,比如模糊控制的主要數據結構FIS的定義,原先的定義如下:
typedef struct fis_node {int handle;int load_param;char name[STR_LEN];char type[STR_LEN];char andMethod[STR_LEN];char orMethod[STR_LEN];char impMethod[STR_LEN];char aggMethod[STR_LEN];char defuzzMethod[STR_LEN];int userDefinedAnd;int userDefinedOr;int userDefinedImp;int userDefinedAgg;int userDefinedDefuzz;int in_n;int out_n;int rule_n;int **rule_list;DOUBLE *rule_weight;int *and_or; /* AND-OR indicator */DOUBLE *firing_strength;DOUBLE *rule_output;/* Sugeno: output for each rules *//* Mamdani: constrained output MF values of rules */struct io_node **input;struct io_node **output;DOUBLE (*andFcn)(DOUBLE, DOUBLE);DOUBLE (*orFcn)(DOUBLE, DOUBLE);DOUBLE (*impFcn)(DOUBLE, DOUBLE);DOUBLE (*aggFcn)(DOUBLE, DOUBLE);DOUBLE (*defuzzFcn)();DOUBLE *BigOutMfMatrix; /* used for Mamdani system only */DOUBLE *BigWeightMatrix;/* used for Mamdani system only */DOUBLE *mfs_of_rule; /* MF values in a rule */DOUBLE *bias; /*bias, to be tuned when no rules are fired*/int isbias;struct fis_node *next; } FIS;上述的定義中,defuzzFcn這個指針函數的定義沒有參數,而后面的Defuzzification methods都是帶參數的,甚至第一個參數就是FIS結構體本身,如: static DOUBLE defuzzCentroid(FIS *fis, int m, DOUBLE *mf, int numofpoints)
所以要修改這個定義,如下: typedef struct fis_node FIS;typedef struct fis_node {int handle;int load_param;char name[STR_LEN];char type[STR_LEN];char andMethod[STR_LEN];char orMethod[STR_LEN];char impMethod[STR_LEN];char aggMethod[STR_LEN];char defuzzMethod[STR_LEN];int userDefinedAnd;int userDefinedOr;int userDefinedImp;int userDefinedAgg;int userDefinedDefuzz;int in_n;int out_n;int rule_n;int **rule_list;DOUBLE *rule_weight;int *and_or; /* AND-OR indicator */DOUBLE *firing_strength;DOUBLE *rule_output;/* Sugeno: output for each rules *//* Mamdani: constrained output MF values of rules */struct io_node **input;struct io_node **output;DOUBLE (*andFcn)(DOUBLE, DOUBLE);DOUBLE (*orFcn)(DOUBLE, DOUBLE);DOUBLE (*impFcn)(DOUBLE, DOUBLE);DOUBLE (*aggFcn)(DOUBLE, DOUBLE);//DOUBLE (*defuzzFcn)(); hemmingway <hemmingway@163.com> 2013/01/02DOUBLE (*defuzzFcn)(FIS *fis, int m, DOUBLE *mf, int numofpoints); DOUBLE *BigOutMfMatrix; /* used for Mamdani system only */DOUBLE *BigWeightMatrix;/* used for Mamdani system only */DOUBLE *mfs_of_rule; /* MF values in a rule */DOUBLE *bias; /*bias, to be tuned when no rules are fired*/int isbias;struct fis_node *next; } FIS;
接下來是printf和double的宏定義問題,原先針對的是控制臺程序,或者Linux下控制臺,如果要把模糊控制用到MFC環境,需要修改這個宏定義,方便用到MFC界面程序中,修改過后如下所示:
/* Define portable printf and double */ #if defined(MATLAB_MEX_FILE) # define PRINTF mexPrintf # define DOUBLE real_T #elif defined(__SIMSTRUC__) # define PRINTF ssPrintf # define DOUBLE real_T #elif defined(_MSC_VER)#define PRINTF odprintf#include <stdarg.h> #include <Windows.h>int _cdecl odprintf(const char* fmt, ...) {char buf[4096], *p=buf;va_list args;int ret = -1;va_start(args, fmt);ret = vsnprintf_s(p, sizeof(buf), _TRUNCATE, fmt, args);p +=ret;va_end(args);while (p>buf && isspace(*p)){*--p = '\0';*p++ = '\r';*p++ = '\n';*p = '\0';}OutputDebugStringA(buf);return(ret); } #else # define PRINTF printf # define DOUBLE double #endif接下來修改一下fisError這個函數,里有有個exit(1); 在MFC界面程序中不需要這個的,需要修改一下:
static void fisError(char *msg) { #ifdef MATLAB_MEX_FILEmexErrMsgTxt(msg); #elsePRINTF("%s\n",msg);#ifndef _MSC_VERexit(1); #endif#endif }還有一個函數封裝了fopen()函數打開文件,里面有個多余的定義語句, FILE *fopen(); ?這個在C++中不支持,需要注釋掉它:
/* an friendly interface to fopen() */ static FILE *fisOpenFile(char *file, char *mode) {FILE *fp /*, *fopen()*/;if ((fp = fopen(file, mode)) == NULL){PRINTF("The file %s cannot be opened.", file);fisError("\n");}return(fp); }再就是fis.c文件后面的幾個函數定義,使用 __STDC__ 宏支持了一種老舊的語法格式,如下所示:
/* return data matrix */ DOUBLE ** #ifdef __STDC__ returnDataMatrix(char *filename, int *row_n_p, int *col_n_p) #else returnDataMatrix(filename, row_n_p, col_n_p) char *filename; int *row_n_p; int *col_n_p; #endif { //code... }問題是MFC程序中 定義 __STDC__ 宏會出現錯誤的,而那種默認的老舊C語法格式C++中又不支持,所以所有這樣定義的函數都要刪掉那些多余的東西,如上面的函數改成這樣: /* return data matrix */ DOUBLE **returnDataMatrix(char *filename, int *row_n_p, int *col_n_p) { //code... }
改完以后,沒有錯誤了,用下面的語句將fis.c文件包含到一個CPP文件的時候,問題又來了,出現?fatal error LNK1169: 找到一個或多個多重定義的符號,按照一般在網上搜索的解決方法是:在項目->屬性->鏈接器->命令行->附加選項中加 /force ?這樣沒有錯誤了,但是還是有很多警告Warning Link 一大堆亂七八糟的警告,其實真正的方法是:在【解決方案資源管理器】中選中fis.c文件,單擊右鍵的屬性,打開fis.c屬性頁對話框,在?【配置屬性】->【常規】->【項類型】中,將這個配置為【C/C++ 標頭】,這樣就沒有什么問題了。
/*Start of the regular fis control*/ extern "C"{ #include "fis.c" }? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
?
============================================
使用方法總結如下:
/** 這是修改過后的fis.c模糊推理系統庫函數,可以移植C/C++環境使用,在VS2010的MFC環境經過測試* 1、將fis.c文件拷貝到項目中;* 2、修改VS2010的配置屬性,項目->屬性->C/C++->預處理器->預處理器定義,添加* _CRT_SECURE_NO_WARNINGS* 3、在【解決方案資源管理器】中選中fis.c文件,單擊右鍵的屬性* 【配置屬性】->【常規】->【項類型】,配置為【C/C++ 標頭】* 4、如果是C語言文件(*.c)使用* #include "fis.c"* 包含接口庫文件;* 5、如果是C++文件,使用* extern "C"{* #include "fis.c"* }* 包含庫文件。* 祝你使用愉快!* hemmingway <hemmingway@163.com> 2013/1/2*/修改過后的fis.c文件可以從這里下載:
http://download.csdn.net/detail/hemmingway/4953923
總結
以上是生活随笔為你收集整理的C/C++实现模糊控制,借助MATLAB辅助设计和fis.c文件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 消息称台积电考虑在德国德雷斯顿建厂,团队
- 下一篇: vivo 应用商店 9.0 版本上线,U