以神經網絡使用爲例的Matlab和Android混合編程

因爲須要在一個Android項目中使用神經網絡,而通過測試發現幾個Github上開源項目的訓練效果就是不如Matlab的工具箱好,因此就想在Android上使用Matlab神經網絡代碼(但是。。。)
這個問題大概處理了兩天,本來預計5個小時的。。。
過程遇到了諸多一手坑以及看到相關資料的對新手不友好,因此就把過程記錄下來但願能給後來者一些幫助
這個教程從0開始講如何在Android App中使用Matlab的神經網絡代碼
整個過程大概能夠分紅這麼幾步:
  1. 首先你要在Matlab中寫一個完整的神經網絡
    1. 獲取樣本
    2. 樣本導入
    3. 神經網絡建模
    4. 神經網絡訓練
    5. 神經網絡測試(優化建模)
  2. 而後你要在Matlab中重寫一個神經網絡,第二個神經網絡的特殊之處是
    1. 首先這個神經網絡必須寫成函數,具體有幾個細節
    2. 把第一個神經網絡的訓練結果net網絡保存成mat文件
    3. 把相關須要用的但沒法直接寫入代碼的數據也保存成mat文件(好比數據歸一化的參數)
    4. 而後在函數中把上面幾個mat文件導入,基本上就是一個完整的神經網絡模型了
    5. 再加上一個神經網絡計算語句,並把結果返回,這個函數就完成了
  3. 而後把這個Matlab神經網絡函數進行打包,打包的結果是一個jar包
  4. 而後把這個jar包連同另外一個jar包一塊導入Andorid工程,並添加爲外部依賴
  5. 最後在Android工程中寫一個專門調用這個jar包接口代碼的函數,傳入輸入變量,返回計算結果
  6. ()
 
1.在Matlab中寫一個完整的神經網絡
1.1.獲取樣本就不說了
1.2.樣本導入
如何導入數據呢,通常matlab中有通用的數據存儲格式,那就是Mat格式,可是我並不知道怎麼編寫這個格式
在我發現有辦法能夠把txt中的數據導入進去以後我就選定它了,由於這種格式也很是方便我用android輸出,也就是說它是一種比較通用的信息交換格式
具體的操做方法很是簡單:
  1. 你在txt中按這種格式保存數據:每行用回車隔開,每列用空格隔開
  2. 而後你在matlab中load這個文件,就能獲得一個數據的矩陣了
代碼以下:
 
alldata = load('alldata.txt');
alldata = alldata(:,:);
 
1.3. 1.4. 1.5. 這幾個過程照着代碼修改仍是比較簡單的(雖然matlab好久沒用讓我當時讀得有點困難。。。),稍微提這麼幾點:
  1. (把經典書目《MATLAB神經網絡30個案例分析》的源碼包放到工做路徑再進行閱讀修改)
  2. 輸出數據須要進行一下矩陣轉換
  3. 使用newff工具函數來構建神經網絡,使用matlab內部的工具箱(其實就是庫函數)來建模、訓練和計算,不須要本身寫邏輯代碼
  4. 中間各類矩陣的變換感受不是很習慣,能夠參看一下工做空間裏的變量狀態,或者一步步打印一些變量的結果來看
 
clc;
clear;
 
%導入300組數據
alldata = load('alldata.txt');
alldata = alldata(:,:);
 
%輸入輸出數據
input = alldata(:,2:33);
outputtemp = alldata(:,1);
%輸出數據須要處理一下
output = zeros(300,2);%預先分配內存
for i=1:300
    switch outputtemp(i)
        case 0
            output(i,:) = [1 0];%意思是若是數據結果是0,則輸出層的狀態是[1 0],或者用第一個輸出節點表示
        case 1 %能直接識別帶小數位的數據
            output(i,:) = [0 1];
    end
end
 
%從中隨機抽取280組數據做爲訓練數據,20組數據做爲預測數據
k = rand(1,300);
[m,n] = sort(k);
 
input_train = input(n(1:280),:)';
output_train = output(n(1:280),:)';
 
input_test = input(n(281:300),:)';
output_test = output(n(281:300),:)';
 
%輸入輸出數據進行歸一化處理
[inputn,inputps] = mapminmax(input_train);
[outputn,outputps] = mapminmax(output_train);
 
%網絡結構構建32-6-2
net=newff(inputn,outputn,6);
 
%網絡參數配置(迭代次數,學習率,目標)
net.trainParam.epochs=100;
net.trainParam.lr=0.1;
net.trainParam.goal=0.0004;
 
%網絡訓練
net=train(net,inputn,outputn);
 
%BP網絡預測
%預測數據歸一化
inputn_test=mapminmax('apply',input_test,inputps);
 
%網絡預測輸出
an=sim(net,inputn_test);
 
%網絡輸出反歸一化
BPoutput=mapminmax('reverse',an,outputps);
 
%結果分析
figure(1)
plot(BPoutput,':og')
hold on
plot(output_test,'-*');
legend('預測輸出','指望輸出')
title('BP網絡預測輸出','fontsize',12)
ylabel('函數輸出','fontsize',12)
xlabel('樣本','fontsize',12)
%預測偏差
error=BPoutput-output_test;
 
figure(2)
plot(error,'-*')
title('BP網絡預測偏差','fontsize',12)
ylabel('偏差','fontsize',12)
xlabel('樣本','fontsize',12)
 
figure(3)
plot((output_test-BPoutput)./BPoutput,'-*');
title('神經網絡預測偏差百分比')
 
errorsum = sum(abs(error))
 
最後輸出的結果還能夠,雖然正確率通常,由於樣本太少 。可是還能接受,是能夠解釋的結果:
 

 

 
2.在Matlab中重寫這個神經網絡,爲導出jar包作準備
2.1.首先這個神經網絡必須寫成函數
在matlab寫一個函數的過程是這樣的
  1. 在工做空間中右鍵新建函數,重命名後打開,就是這樣
  2. matlab中的函數在這裏一塊兒趁熱講了(本身複習一遍)
    1. 整個函數有一頭一尾兩句固定的聲明,頭是以function開始,而後是:返回值 = 函數名(函數參數),尾是end,雖然一開始看得不適應,可是習慣仍是很好理解的,跟其餘的語言差很少
      1. 返回值能夠沒有,那就是直接 函數名(函數參數)
      2. 返回值能夠有多個,參數也能夠有多個,他們的形式是這樣:function [x,y,z]=sphere(theta,phi,rho)
      3. 注意Matlab中不會對函數類型進行聲明,因此不少時候你在寫函數的時候一開始就要對輸入參數進行一個檢查 
    2. 而後下面接着是官方註釋,第一句是摘要,以後是詳細說明,這些東西會在預覽的時候顯示
    3. 接下來就是函數體了,你能夠作各類事情,邏輯語句、調用其餘函數
    4. 最後在end以前你須要定義返回值,matlab在這塊有點特殊,你不用顯示地指定return哪一個變量,由於你第一句聲明裏有返回值變量,因此只要你的函數內容中有這個變量,那麼最後執行到end的時候就會自動返回這個變量這時候的狀態
    5. -----調用函數------
    6. 調用函數的形式跟函數聲明的第一句是一毛同樣的:[輸出參數表]=函數名(輸入參數表)
    7. 調用函數時,輸入和輸出參數的順序應與函數定義時的一致,數目必定不能多於函數定於中的,可能能夠少於
    8. 爲何能夠少於,由於在函數內部能夠經過nargin()和nargout()獲取函數被調用時用戶指定的輸入、輸出參數個數。因此若是這個函數裏邊有針對不一樣的少於輸入少於輸出的狀況進行if else的話,就能夠自動適應
  3. 那麼在這裏,個人輸出是一個int,輸入是一個行矩陣,或者說一個數組,個人函數開頭就這麼寫了:
    function output = annforecastthi(input_test)
 
2.2.而後爲了避免在這個函數裏對神經網絡進行訓練(由於matlab的設定就是沒法把訓練函數編譯成Jar包),須要把先前神經網絡中訓練好的net保存成mat文件再在這裏直接導出
  1. 把先前神經網絡中訓練好的net保存成mat文件 很是簡單。直接在運算結束後再工做空間中右鍵net變量,保存爲mat文件就能夠了
  2. 而後導入的時候稍微有點麻煩
    1. 其實load mat文件有兩種方式,一種是命令行方式,一種是函數方式。兩種方式功能上沒什麼區別,可是推薦在函數裏用函數方式
    2. 以導入一個結構體(歸一化參數)爲例:
      1. 命令行方式 :load anninputps inputps;
      2. 函數方式:
    3. 而導入net數據的時候還要麻煩一些:
      1. 命令行方式:load annnet net;
      2. 函數方式:(後邊還要加一句把結構體轉型成網絡格式)
  3. 這裏須要導入三個mat文件,一個net和兩個歸一化參數(後邊要用來反歸一化)
 
關於爲何不能把神經網絡的訓練函數編譯成jar包
MATLAB官方論壇中看到這樣一個回答:
You will not be able to compile any function which trains the network (like ADAPT). Though the link does not explicitly list these funcions (like ADAPT), they fall under the 'All other command line functionality'.
However, you can deploy a M function code which uses a pre-trained network. I believe the SIM function will deploy fine.
The workflow I see is:
1. In MATLAB, train you network using test input/output
2. Save the network (mat file?)
3. Create a deployable function which then uses the pretrained network for new data. The network itself would not change/adapt/train in this function
4. Compile and deploy the above function
大意:MATLAB compile不支持對神經網絡工具箱中涉及到訓練的函數命令進行編譯,只能編譯那些用在已訓練好的網絡上的函數命令
因此解決方法就是在matlab下訓練好網絡,將net保存爲mat文件,而後再寫一個m文件,load進mat文件
 
2.3.最後返回計算結果,第二個神經網絡模型也是神經網絡計算函數就完成了
output=find(BPoutput(:,1)==max(BPoutput(:,1)));
整個函數是這樣:
 
function output = annforecastthi(input_test)
%ANNFORECAST
%   輸入長度爲32的行矩陣,輸出爲1或2
 
A = load( 'annnet.mat' );
B = fieldnames(A);
net = A.(B{1});
net = network(net);
 
C = load( 'anninputps.mat' );
D = fieldnames(C);
inputps = C.(D{1});
 
E = load( 'annoutputps.mat' );
F = fieldnames(E);
outputps = E.(F{1});
 
%BP網絡預測
%預測數據歸一化
inputn_test=mapminmax( 'apply' ,input_test',inputps);
 
%網絡預測輸出
an=sim(net,inputn_test);
 
%網絡輸出反歸一化
BPoutput=mapminmax( 'reverse' ,an,outputps);
 
%結果分析
%根據網絡輸出找出數據屬於哪類
output=find(BPoutput(:,1)==max(BPoutput(:,1)));
 
end
 
3.把這個Matlab神經網絡函數打包成一個jar包導出
3.1.吐槽
3.2.安裝java開發環境
  1. 安裝java開發環境是很簡單的事情,正常的步驟是這樣
    1. 去甲骨文的官網下最新的jdk文件
      1. 選擇windows64位的下載
      2. 不要選jre,區別是jre只能用來運行,不能用來編譯,它也比jdk要小不少
      3. 這個網站下東西可能很慢,這個時候能夠自行搜索一些網盤裏提供的
    2. 點擊這個jdk.exe文件進行安裝,安裝過程沒什麼好說的
    3. 安裝無缺像說如今的jdk不配置環境變量也不要緊,但之前的要配置環境變量,那就配置吧,這個會單獨在後邊寫
  2. 而後我實際上是以前就有安裝的,可是在後邊生成Jar包的時候出現了問題
    1. 通過排查,發現是jdk的版本相對matlab版本過高了:目前個人這個matlab2015b對應的是jdk7,因此我如今jdk8都不能夠。(參考:matlab 2014a 用jdk1.7;matlab 2013a 用jdk1.6)
    2. 因而就只能下降jdk版本了,如何下降呢,其實很簡單,你的系統中是能夠同時安裝多個jdk版本的不會衝突,最後你但願編譯的時候用哪一個版本,就在環境變量裏配置哪一個版本,很是方便
    3. 可是下載的時候也會遇到個問題,由於官網找不到舊版本的下載,我就是搜索了一個而後安裝,安裝完修改了一下環境變量,最後ok了
 
3.3.配置環境變量
  1. 配置JAVA環境變量
    1. 具體的作法是:
      1. 個人電腦——屬性——高級設置——高級——環境變量
      2. 在系統變量裏添加一個鍵值對:JAVA_HOME(大小寫不敏感),和jdk安裝後的位置路徑(爲javac.exe所在目錄D:\Program Files\Java\jdk1.6.0_13\bin的上一層)
      3. 配置完以後這樣能夠驗證
    1. 另外說一點是,即便配置了這個java path,但Eclipse和AS中還有獨立的配置:
      Eclipse:Window -> Preferences->Java -> Compiler 設置 "Compiler compliance level" 爲 1.6 (相應版本)
      AS:點擊File,選擇Other Settings,選擇Default Project ,Structure...
  2. 配置path
    1. 也是在系統變量裏添加
    2. 變量名是path,值是【.;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;D:\Program Files\MATLAB\R2015b\bin】
    3. 如今我實際上是這樣的,竟然也能夠,不是很懂 【%Java_Home%\bin;%Java_Home%\jre\bin;C:\ProgramData\Oracle\Java\javapath;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Calibre2\;C:\Program Files\MATLAB\R2015b\runtime\win64;C:\Program Files\MATLAB\R2015b\bin;C:\Program Files\MATLAB\R2015b\polyspace\bin;C:\Program Files\MATLAB\MATLAB Runtime\v90\runtime\win64】
  3. 配置CLASSPATH
    1. 也是在系統變量裏添加
    2. 變量名是path,值是【.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar;D:\Program Files\MATLAB\R2015b\toolbox\javabuilder\jar\javabuilder.jar;%JAVAHOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar】
    3. 如今我實際上是這樣的,竟然也能夠,不是很懂【.;%Java_Home%\bin;%Java_Home%\lib\dt.jar;%Java_Home%\lib\tools.jar】
 
3.4.打包的操做
在2015版本中操做跟前面版本的可能有很大的不一樣(跟2013都不同,前面的也各自不同orz),就只說在這個版本中的步驟
  1. 在命令行區域輸入命令:deploytool,彈出對話框,而後你選擇第三個library compiler
  2. 因而打開了一個大界面,在這個界面裏要作五件事
    1. 1這選擇java
    2. 2這點擊添加你的這個m函數(2旁邊這個框保持原樣,不用打鉤)
    3. 3這塊通常都會改一你以爲適合的名字
    4. 關鍵4這必定要把你m函數中load的數據文件一塊加進來
    5. 點擊開始打包
  3. 打包須要一點時間,結束後若是成功就會在工做空間路徑下生成一個項目,項目中能找到輸出Jar文件,這個就是咱們的要的

     

四、把jar導入工程中
  1. 除了剛纔生成的這個Jar包以外,還須要導入另外一個Jar包,這個jar包就是MATLAB中帶的jarbuild.jar 這個包,通常路徑是E:\Program Files\MATLAB\R2013a\toolbox\javabuilder\jar   (MATLAB解析jar包文件)
  2. 用AS往Android工程導入JAR包的步驟是這樣的
    1. 將jar文件複製、粘貼到app的libs目錄(app—src—main—libs)中(此時雖然jar已經複製黏貼過來了,可是還未導入,因此看不到jar中包含的內容。而已導入的jar,則能夠看到jar中內容)
    2. 右鍵點擊jar文件,並點擊彈出菜單中的「Add As Library」,將jar文件做爲類庫添加到項目中
    3. 刪除jar包 的步驟
      1. 選中項目
      2. 點擊 File——>Project structure——>module——>app
      3. 選擇 「dependencies」,選擇你要刪除的jar包,點擊減號
  3. 用Eclipse往JAVA工程導入JAR包的步驟是這樣的
    1. 在java工程下新建一個lib文件夾(不新建也行,只是爲了規範),直接把jar包拖入這個文件夾
    2. 右鍵,添加依賴
 
五、寫一個專門的工具方法做爲調用Matlab函數的接口,傳入輸入變量,返回計算結果
怎麼寫:
  1. 導入結束後,你能看到實際上是這樣的
  2. 因此你寫接口的話很是簡單
    1. 先new一個這個類,而後調用類的這個方法,輸入輸出
    2. 直接結束
而後寫的話須要注意這麼幾點:
  1. (參數和返回值的數據類型什麼的,matlab 的幫助文檔matlab builer for JA中說得很詳細)
  2. 必須catch一下MWException,這個是matlab裏邊的
  3. 輸入:
    1. 你的matlab函數是這樣寫的:output = annforecastthi(input_test)
    2. 你的函數裏是把輸入當成一個大小爲32的行矩陣來用的,因此正常想在這應該是輸入一個數組
    3. 可是根據代碼提示,你會發現不徹底是這樣,而是:第一個參數是輸出數據個數,以後是一個個的輸入數據,輸入數據能夠直接是一個數組
  4. 輸出:
    1. 一樣,我在matlab函數裏寫的輸入是一個int值,爲1或者2
    2. 可是在這裏,你的輸出是一個Object[ ],若是輸出只有一個的話,那就是result[0]
    3. 另外若是result[0]返回的是一個數組,能夠經過以下的方法解析(供參考)
      1. MWNumericArray a = new MWNumericArray(Double.valueOf(result[0].toString()),MWClassID.DOUBLE);
      2. MWNumericArray temp = (MWNumericArray)result[0];
      3. float [][] weights=(float[][])temp.toFloatArray();
 
public class TestMatlab {
       
public static void main(String[] args){
              
try {
                     ANNMatlab annMatlab = new ANNMatlab();
                      double [] array = { 74.5 , 75.5 , 83.3 , 93.4 , 93.9 , 90.1 , 86.1 ,... };
                     Object result[]=annMatlab.annforecastthi( 1 ,array);
                     // 函數第一個參數是輸出數據個數,以後的就是 是輸入數據。
                                     System. out .println( "result==" +result[ 0 ]);
              }
catch (MWException e) {
                     e.printStackTrace();
              }
       }
}
 
而後在JAVA項目中運行,得到了正確的輸入
可是當把這個項目放在Android項目中運行的時候,發現崩潰而且報錯了
 
 
六、Android項目中沒法直接使用Matlab中導出的jar包
根據前文的正確操做到這一步的時候,你會發現Android項目仍是崩潰了,而且報這樣的錯
【java.lang.UnsatisfiedLinkError: Failed to find the required library libmwmclmcrrt.so.9.0 on java.library.path. 】
這個錯誤的意思是:在java路徑上缺乏這個so文件
這個java路徑能夠經過【 System. out .println(System. getProperty( "java.library.path" )); 】這句代碼打印,我這裏打印結果是zycn根文件夾,也就是整個項目的根文件夾
而這個libmwmclmcrrt.so.9.0又是什麼呢
  1. so文件和dll文件都是動態連接庫(說白了就是一些庫函數),dll文件是windows系統中使用的,而so文件是Linux系統中使用的
  2. 而這個libmwmclmcrrt.so.9.0大概是matlab代碼須要的,可是爲何須要呢?不該該搞定以後都會有嗎?
    1. 搜索引擎上一些缺乏.so文件的問題發生在Linux系統下,而後他們的解決辦法都是一個,從新配置環境變量,由於好像在linux上配置這個環境變量很容易出問題(https://www.baidu.com/s?ie=UTF-8&wd=libmwmclmcrrt.so.9.0)(http://blog.csdn.net/chujiangke001/article/details/17427659)(http://www.linuxidc.com/Linux/2013-03/80301.htm)(http://www.aiuxian.com/article/p-2193879.html)(http://blog.csdn.net/xcmax/article/details/27523419)(http://www.aiuxian.com/article/p-2193879.html
    2. 搜索引擎上還有缺乏dll文件的,一部分是環境變量的配置問題,一部分是須要手動安裝某個800多M的文件(若是你要在沒有安裝matlab的機器上用java調用這些jar包,怎麼辦?也是能夠的,不過,不過你要先在機器上安裝matlab提供的MATLAB Compiler Runtime (MCR) ,它的安裝文件在D:\program files\study\MATLAB\R2007b\toolbox\compiler\deploy\win32下(你的安裝目錄下)文件名MCRInstaller.exe)(http://www.cnblogs.com/ellisonDon/archive/2012/10/30/2746457.html)(http://jingyan.baidu.com/article/ab0b5630b801ddc15afa7df1.html
    3. 但這裏由於在java項目中能成功運行,在android中不行,因此天然會想到是android系統的環境變量配置問題或者說就是跟android系統有關
後來在matlab官方論壇和stackoverflow上更換了下關鍵詞【直接matlab+android】,有找到對於這個問題的直接解釋,還有曲線救國的辦法。相關的問題還不少,看來是不少人都遇到了這個問題
 
The .jar files that Compiler SDK generates cannot be run on Android. The .jar has a small interface to call upon the machine code library that is MCR, and otherwise the .jar contains encrypted data files. The encrypted data files are the "compiled" .m code, which is not compiled to java, but rather to MATLAB's internal threaded interpreter. MCR decrypts the encrypted pcode'd .m files and uses them as data to be processed by the threaded interpreter. The encrypted data files themselves can be fairly operating system independent, but you need MCR to interpret them, and MCR is in x86 or x64 machine code for all versions of MATLAB since about R2009a. Android does not run on x86 or x64: Android runs on ARM processors (or possibly PowerPC as well, I am not certain.)
In short, you cannot use Compiler SDK to generate for anything useful on Android.
At this time, the only way to deploy for Android is to use Simulink with Target set to Android. You can have your Simulink blocks call a MATLAB Function block which is specialized MATLAB code (that has to be careful about how it allocates memory.) There is not much graphics you can do with this mechanism but it is the best that is available at this time.
I happened to look last night at some of the blocks available for deployment to a couple of the Android Galaxy devices. There is a block which accepts R, G, and B signals and displays the result as the screen. It would require computing the entire screen, I suspect. Some of the routines in the Vision toolbox help in that.
大意:matlab生成的jar包不能直接在android上運行,還須要用一個叫MCR的東西進行解碼(The MATLAB Compiler Runtime (MCR) has the same System requirements as MATLAB. See System Requirements - Android is not one of them.它是matlab代碼解析器),而MCR目前只能運行在X86或者X64的CPU上,但由於android是運行在ARM CPU上,因此是不可能使用的。
而後它說:此時,部署Android的惟一方法是使用Simulink與目標設定爲Android。你能夠有你的Simulink模塊調用MATLAB函數的MATLAB代碼塊是專業(需注意如何分配內存)沒有多大的圖形能夠作這種機制,但它是最好的,此時可用。
後邊這個就看不懂了:我碰巧看的最後一個晚上的一些塊可供部署到一對夫婦的安卓銀河設備。有一個塊,它接受R,G和B信號,並顯示屏幕的結果。它將須要計算整個屏幕,我懷疑。一些例程中的「視覺工具箱」中的幫助。
 
I have not read about what can be done in R2016a. The situation as of R2015b was that in order to generate code for Android from MATLAB, what you needed to do was include the MATLAB code in a MATLAB Function block in Simulink and tell Simulink to target Android; there was no direct path for MATLAB to Android.
大意:你須要作的是包括在Simulink MATLAB功能塊的matlab代碼告訴Simulink目標Android
 
However, you should be able to use the MATLAB Coder product to generate a standalone C/C++ library from your MATLAB code and then invoke that from your Android application, possibly using JNI.
大意:你可使用一個叫MATLAB Coder的工具來生成能夠獨立運行的C/C++庫,他們能夠在android中經過JNI來直接運行
 
MATLAB code that is put into a Simulink MATLAB Function Block (with appropriate adjustments made) can be generated for Android target using Simulink. There are a bunch of restrictions on this, but I think it can access the Android Sensor information for supported devices (Galaxy S4, Galaxy Note 2)
大意:matlab代碼,把MATLAB的一個Simulink功能塊(適當調整)能夠爲Android使用Simulink生成目標。有一些限制,但我認爲它能夠訪問支持的設備Android傳感器信息(Galaxy S4,Galaxy Note 2)
 
From MATLAB, you can communicate with Android camera and with Android sensors (at least for some models), but it is not possible to generate code for Android. You need to use Simulink to generate code for Android.
MATLAB Coder does not know about Android, so MATLAB Coder cannot generate Android calls for user interaction, networking, graphics, and so on. MATLAB Coder can generally generate C or C++, but unless it has been given information about the target system, MATLAB Coder has a library of calls that is not even as complete as the Standard C Library. This is not enough to create an Android "app"; at most it is enough to create a utility program.
Simulink does know how to target Android, so if you have a Simulink model and use the Android-specific blocks, Simulink can create apps. See http://www.mathworks.com/hardware-support/android-programming-simulink.html
大意:能夠用Simulink
 
.so files are Linux Shared Object libraries. Those .so files are only available for Intel x86 (32 bit) and x64 (64 bit) instruction set (including AMD CPUs that implement those.) They are not available for ARM or other instruction architectures.
大意:.so文件自己也只能再X86的系統上使用,而不能在ARM上使用(這個存疑)
 
The .jar file requires the MATLAB Compiler Runtime (a freely redistributable component that you get with MATLAB Compiler and MATLAB Builder products) to be present. The MCR has a much larger footprint than is suitable for the typical Android device (it's like a copy of MATLAB itself, without the user interface).
You could think about either
1)Running your MATLAB .jar file remotely on a server, and having your Android application connect to it, or
2)Instead of using MATLAB Compiler and Builder products, use MATLAB Coder, which will convert a subset of the MATLAB language directly into C code. This C code doesn't require the MCR, and could be compiled to run directly on Android. Make sure your MATLAB algorithm falls within, or can be expressed in, the appropriate subset of the MATLAB language.
大意:前面都同樣不說了,後邊提了兩個解決辦法:1)不要再app上用Matlab代碼,轉移到服務器上;2)用 MATLAB Coder編譯成能夠不須要MCR支持才能運行的C/C++文件
 
A new feature in Matlab 2014a:
http://www.mathworks.com/help/simulink/samsung-galaxy-android-devices.html
You can now directly install (limited set of) models to Samsung Android devices, and this should work actually on any Android device.
大意:2014的新版本中,你能夠直接把matlab模型安裝在三星安卓設備上,實際上就能夠安裝在全部安卓設備上
 
總結一下上面的內容:
  1. 直接在android app上使用deploytool生成的jar包是不行的,由於它不能獨立運行,還須要MCR的支持,而因爲CPU的緣由MCR是不能運行在android環境的
  2. 那麼其餘可行的間接辦法有這些
    1. 不要在app上用Matlab代碼,轉移到服務器上
    2. MATLAB Coder編譯成能夠不須要MCR支持才能運行的C/C++文件,而後使用JNI的方法在android app上使用
    3. 能夠經過一種【include the MATLAB code in a MATLAB Function block in Simulink and tell Simulink to target Android】的方法來作
 
對於第一個間接辦法,確定是可行的,但因爲目前我這條件的限制,是沒法實現了
對於第二個間接辦法,確定也是可行的,不過稍顯複雜,目前我對此也沒有涉獵
對於第三個間接辦法,我去簡單瞭解了一下,可是搞下來毫無頭緒:
  1. 首先我沒有找到step by step的教程,因此只能一個個本身去搜索
  2. 因而先去看了matlab的simulate系統,兩個感覺:
    1. 功能很是豐富繁雜
    2. 找不到所謂的跟搞一個android虛擬機有關的東西
    3. 這個中文入門教程還能夠:http://wenku.baidu.com/link?url=40Z4TdIwCDm35TsAmk8NgVwL1UtJzYoVhe8dwKs87kytiIUx25kIgU18zJcV65UTH7kgHyh0Cfq-pGgDjdrXeSE5j3f_B1vmwG284hTiyQG
  3. 而後我看了下這個什麼三星虛擬機,發現:這個東西好像只是跟什麼傳感器有關,能夠在matlab中獲取三星手機傳感器的數據,跟我如今的需求沒有關係
    1. http://cn.mathworks.com/examples/simulink/mw/android_product-androidusageexample-working-with-samsung-galaxy-android-devices-block-library?s_tid=srchtitle
    2. https://www.baidu.com/s?wd=matlab%20android&pn=30&oq=matlab%20android&ie=utf-8&rsv_pq=c9a5520000070f35&rsv_t=9669WDl4Z8FRLpkV6StuMtaAWluCKlVLBmZBF1KUbEB63kqnQiyTeEhD7jo&rsv_page=1
  4. 最後時間關係沒有繼續探索下去
 
七、另外一個解決辦法
其實推薦使用上面的第一個或第二個間接辦法,都很不錯
不過最後我採用了個間接可是比較簡單可能效果很差的方法:直接找了一個java寫的神經網絡開源項目,讀了一下了解怎麼用,就直接放進app中使用了
因此這個教程其實還差一步沒有結束,以後有空把JNI學一下再來更新這個部分
 
參考資料:已在文中列出
相關文章
相關標籤/搜索