シリアル受信プログラムができる見込みなので、データ処理の準備にかかってます。
■計算目的:
自作6分力センサの出力と校正負荷から、6分力センサのひずみゲージ変換係数を干渉補正計算(一般化逆行列、MoorePenrose逆行列)をするプログラムを組むのが目的です。
■多軸力覚センサの干渉補正計算の基礎
【ロードセル】干渉補正式の基礎再学習<2年ぶり>
【ロードセル】Processing_MatrixライブラリーでMP逆行列計算<転置だけ自作した>
Processingのライブラリでは、計算できるようになったので、VB.NETでもライブラリー探してやってみました
■.NET 用 行列計算ライブラリImagingsolution様に感謝
[VB.NET 行列ライブラリ」1年以内検索のTOPにでてきました。
※2020年11月追記 結局使えませんでした
実際に計測システムに組み込もうとして3x3以上の行列データをいれてみると、逆行列の計算がNANが多発で、解がでないことがわかりましたので、残念ながらImageSolution様の逆行列は使えませんでした。代替えとして検索した結果、外池幸太郎様が米国のライブラリーをVB.NETに移植したライブラリーがすんなりと動作しました。使い方の記事はこちらです。
行列計算は、精度処理の点で、なかな一筋縄ではいかないと実感してます。
https://imagingsolution.net/program/csharp/dotnet_matrix_class/
この解説記事からライブラリーをダウンロードします。
=>C#用にサンプルプログラムしかありませんが、.NET用なので、VB.NETでも使えました。
①ダウンロードファイル
ImagingSolution.Mat_V011.zip
②解凍すると
解凍フォルダーの3段下に ImagingSolution.Mat.dll があります。
これを参照登録します。
■VisualStudio VB.NETでサンプルプログラム作り
解凍したフォルダーにはC#用のサンプルプロジェクトがあるので
ConsoleSample.csprojをダブルクリックすると、VisualStudio2019が起動して
ソースで下部のbitmap部分は使わないのでコメントアウトして、コンソール画面を保持するために
//キー入力待ちを上に移動させます。これで、開始を押すとコンパイルして下記コンソールに
各種行列計算結果が表示されます。
■C#からVB.NETへ移植
C#のusing=>VB.NETのimports
C#のvar =>VB.NETのDim
C#のコメント//=>VB.NETの’
C#の;=>VB.NETでは無いので削除します
C# | VB.NET 変更点赤 |
// 行列(matA)の設定例(二次元配列で行列を設定) var matA = new double[3, 3]; matA[0, 0] = 1; matA[0, 1] = 2; matA[0, 2] = 3; matA[1, 0] = 4; matA[1, 1] = 5; matA[1, 2] = 6; matA[2, 0] = 7; matA[2, 1] = 8; matA[2, 2] = 9;matA.Print(“matA =”); // コンソールへ行列の表示 |
‘行列(matA)の設定例(二次元配列で行列を設定) Dim matA = new double[3, 3] matA(0, 0) = 1 matA(0, 1) = 2 matA(0, 2) = 3 matA(1, 0) = 4 matA(1, 1) = 5 matA(1, 2) = 6 matA(2, 0) = 7 matA(2, 1) = 8 matA(2, 2) = 9matA.Print(“matA =”)‘コンソールへ行列の表示 |
こういうやり方でC#を全部VB.NETに変換します。
Form1(デザイン)にボタン1個作ってください。
Form1.vbコードはGISTに置いてあります。
https://gist.github.com/dj1711572002/fad0d2250d4d1c45c992651fc352ecba
Imports ImagingSolution ‘ImagingSolution.Matクラス用 Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click ‘========matA==================== Dim matA(2, 2) As Double matA(0, 0) = 1 matA(0, 1) = 2 matA(0, 2) = 3 matA(1, 0) = 4 matA(1, 1) = 5 matA(1, 2) = 6 matA(2, 0) = 7 matA(2, 1) = 8 matA(2, 2) = 9matA.Print(“matA =”) ’ コンソールへ行列の表示 ‘============matB================= Dim matB(2, 2) As Double matB(0, 0) = 1 matB(0, 1) = 4 matB(0, 2) = 8 matB(1, 0) = 6 matB(1, 1) = 2 matB(1, 2) = 5 matB(2, 0) = 9 matB(2, 1) = 7 matB(2, 2) = 3matB.Print(“matB =”) ‘ コンソールへ行列の表示 ‘===========行列(matA)と行列(matA)の積====== Dim matMult = matA.Mult(matB) matMult.Print(“matA matB =”)’===========行列(matA)と行列(matA)の加算====== Dim matAdd = matA.Add(matB) matAdd.Print(“matA + matB =”) ‘===========行列(matA)と行列(matA)の減算====== Dim matSub = matA.Sub(matB) matSub.Print(“matA – matB =”) ‘===========行列(matB)の逆行列============= Dim matInverse = matB.Inverse() matInverse.Print(“(matB)-1 =”) ‘===========行列(matA)の転置============== matA.Print(“matA =”) ’ コンソールへ行列の表示 Dim matTranspose = matA.Transpose() matTranspose.Print(“(matA)T =”) ‘===========回転行列の取得================= Dim matRotate = Mat.RotateMat(10.0) matRotate.Print(“RotateMat =”) ‘===========拡大行列の取得================= Dim matScale = Mat.ScaleMat(2.0, 5.0) matScale.Print(“ScaleMat =”) ‘===========平行移動行列の取得============== Dim matTranslate = Mat.TranslateMat(-5.0, 12.0) matTranslate.Print(“TranslateMat =”)End Sub End Class |
これを実行した結果は、きちんと各種行列計算できてます
‘ System.Double[3,3] 1,2,3 4,5,6 7,8,9matB = System.Double[3,3] 1,4,8 6,2,5 9,7,3matA matB = System.Double[3,3] 40, 29, 27 88, 68, 75 136,107,123matA + matB = System.Double[3,3] 2, 6,11 10, 7,11 16,15,12matA – matB = System.Double[3,3] 0,-2,-5 -2, 3, 1 -2, 1, 6(matB)-1 = System.Double[3,3] -0.107011070110701, 0.162361623616236, 0.014760147601476 0.0996309963099631,-0.254612546125461, 0.158671586715867 0.0885608856088561, 0.107011070110701,-0.0811808118081181matA = System.Double[3,3] 1,2,3 4,5,6 7,8,9(matA)T = System.Double[3,3] 1,4,7 2,5,8 3,6,9 RotateMat = ScaleMat = TranslateMat = |