※OPTOTRACKは3次元位置計測を行える機器です。
--------------------構成: OPTOTRAK - Win32 Debug--------------------
リンク中...
Class_OPTOTRACK.obj : error LNK2001: 外部シンボル "__imp__DataGetLatest3D@16" は未解決です
Class_OPTOTRACK.obj : error LNK2001: 外部シンボル "__imp__OptotrakActivateMarkers@0" は未解決です
Class_OPTOTRACK.obj : error LNK2001: 外部シンボル "__imp__OptotrakSetupCollection@44" は未解決です
Class_OPTOTRACK.obj : error LNK2001: 外部シンボル "__imp__OptotrakLoadCameraParameters@4" は未解決です
Class_OPTOTRACK.obj : error LNK2001: 外部シンボル "__imp__TransputerInitializeSystem@4" は未解決です
Class_OPTOTRACK.obj : error LNK2001: 外部シンボル "__imp__TransputerLoadSystem@4" は未解決です
Class_OPTOTRACK.obj : error LNK2001: 外部シンボル "__imp__TransputerShutdownSystem@0" は未解決です
Class_OPTOTRACK.obj : error LNK2001: 外部シンボル "__imp__OptotrakDeActivateMarkers@0" は未解決です
LIBCD.lib(wincrt0.obj) : error LNK2001: 外部シンボル "_WinMain@16" は未解決です
Debug/OPTOTRAK.exe : fatal error LNK1120: 外部参照 9 が未解決です。
link.exe の実行エラー
OPTOTRAK.exe - エラー 10、警告 0
これはどういう意味のものなのでしょうか?
C++言語の勉強を始めたばかりで、解決策も教えてくださるとありがたいです。
参考として、エラーメッセージに表示されているClass_OPTOTRACK.cppの詳細を下記に示します。
#include "Class_OPTOTRACK.h"
/****************************************************************/
/* オプトトラックからのデータを読み取る関数たち: */
/****************************************************************/
/*****************************************************************
1. Load the system of transputers with the appropriate
transputer programs.
2. Initiate communications with the transputer system.
3. Load the appropriate camera parameters.
4. Set up an OPTOTRAK collection.
5. Activate the IRED markers.
6. Initialize a file for spooling OPTOTRAK raw data.
7. Spool the OPTOTRAK raw data to file.
8. De-activate the IRED markers.
9. Convert the OPTOTRAK raw data file to a 3D data file.
10. Disconnect the PC application program from the transputer
system.
*****************************************************************/
// オプトトラック初期化
void Class_OPTOTRACK::Co_Initial_Set()
{
/*
* 1. Load the system of transputers.
*/
if ( TransputerLoadSystem( "system" ) )
{
Co_longOR_EXIT();
}
//TransputerLoadSystemは決り文句みたいなもの
//引数はsystem.nifのファイル名でtransputer systemをロードするときに用いる
//TransputerInitializeSystemとTransputerShutdownSystemを用いて
//接続,切断を行うために必要
//エラー時には関数がintで宣言されているために値が返ってくる
//値0のとき成功,1のとき失敗
/*
* 2. Initialize the transputer system.
*/
if ( TransputerInitializeSystem( 0 ) )
{
Co_longOR_EXIT();
}
//OPTOTRAKのシステムと通信する為の関数
//引数のunsigned int uFlagsを指定してやる,これから以後に使う関数に
//引数としてこの数値が渡される場合がある.
//エラー時には関数がintで宣言されているために値が返ってくる
//値0のとき成功,1のとき失敗
/*
* 3. Load the standard camera parameters.
*/
if ( OptotrakLoadCameraParameters( "standard" ) )
{
Co_longOR_EXIT();
}
//OptotrakLoadCameraParametersはOPTOTRAKシステムに
//カメラのパラメータファイルの内容を送る関数
//引数は char *pszCamFile でカメラのパラメータデータが入っている
//デフォルトでは引数にSTANDARD.CAMファイルを使用する
//引数には"STANDARD"を入力
//このデータがないと生データを3Dデータに変換できません
//このファイルはキャリブレーションに関係がありそう
//OPTOTRAK COLLECTプログラムでファイル作成できるみたい
//詳しくはOPTOTRAK COLLECT ゆーざーガイド参照
//エラー時には関数がintで宣言されているために値が返ってくる
//値0のとき成功,1のとき失敗
/*
* 4. Set up a collection for the OPTOTRAK.
*/
if( OptotrakSetupCollection(
NUM_MARKERS, /* Number of markers in the collection. */
FRAME_RATE, /* Frequency to collect data frames at. */
(float)2500.0, /* Marker frequency for marker maximum on-time. */
30, /* Dynamic or Static Threshold value to use. */
160, /* Minimum gain code amplification to use. */
1, /* Stream mode for the data buffers. */
(float)0.4, /* Marker Duty Cycle to use. */
(float)7.5, /* Voltage to use when turning on markers. */
COLLECTION_TIME, /* Number of seconds of data to collect. */
(float)0.0, /* Number of seconds to pre-trigger data by. */
OPTOTRAK_BUFFER_RAW_FLAG ) )
{
Co_longOR_EXIT();
}
//ファイル内のパラメータを解析する関数
//ファイル内のパラメータを元に準備を行う
//このファイルもOPTOTRAK COLLECTプログラム
//またはASCII editorで作成できる
//パラメータの詳細はAPPLICATION PROGRAMMER'S INTERFACE GUIDE7-7参照
//エラー時には関数がintで宣言されているために値が返ってくる
//値0のとき成功,1のとき失敗
/*
* 5. Activate the markers.
*/
if ( OptotrakActivateMarkers() )
{
Co_longOR_EXIT();
}
//マーカーを作動させる関数
/*
* 6. Initialize a file for spooling OPTOTRAK raw data.
*/
if ( DataGetLatest3D ( &uFrameNumber, &uElements, &uFlags, &p3dData[0] ) )
{
Co_longOR_EXIT();
}
//OPTOTRAKシステムから3Dのフレームのデータを検索する
//このフレームのデータはプログラムによってメモリーに蓄えられる → spooling!
//オーバーフローすると予期せぬ事態に陥るので注意
//uFrameNumber(unsigned int *puFrameNumber)は今対象としているフレームの番号
//uElements(unsigned int *puElements)はマーカーの番号
//uFlags(unsigned int *puFlags)はOPTOTRAKのデータの現在の状態を示す
//p3dData[0](void *pDataDest)はOPTOTRAKのデータが格納されている変数のポインタ
//エラー時には関数がintで宣言されているために値が返ってくる
//値0のとき成功,1のとき失敗
}
// 原点座標系の決定、固定及び原点座標系の回転変換行列Co_RotMatrix作成
int Class_OPTOTRACK::Co_Preparation()
{
int i,j,k;
Cdnt_XYZ OPTOTRAK_X_DATA; //測定者の所望する座標軸X(OPTOTRAKで測定)
Cdnt_XYZ OPTOTRAK_Y_DATA; //測定者の所望する座標軸Y(OPTOTRAKで測定)
Cdnt_XYZ OPTOTRAK_Z_DATA; //測定者の所望する座標軸Z(OPTOTRAKで測定)
//エラーフラグの初期設定
Frag_Err_In = 0;
Frag_Err_Mi = 0;
for(i=0; i<3; i++)
{
Co_Pnt_Marker[i+1].X = 0;
Co_Pnt_Marker[i+1].Y = 0;
Co_Pnt_Marker[i+1].Z = 0;
}
//**************************原点座標系の決定******************************//
//データを100回抽出し90から100番目のデータの平均値を原点座標系と決める
for(k = 0; k <= 100; k++)
{
if( DataGetLatest3D( &uFrameNumber, &uElements, &uFlags, &p3dData[0] ) )
{
Co_longOR_EXIT();
}
if(k > 90 && k <= 100)
{
for(i=0; i<3; i++)
{
Co_Pnt_Marker[i+1].X += (double)p3dData[i].X/10;
Co_Pnt_Marker[i+1].Y += (double)p3dData[i].Y/10;
Co_Pnt_Marker[i+1].Z += (double)p3dData[i].Z/10;
}
}
//得られたデータを原点初期値とする
for(j = 1 ; j <= 3 ; j++)
{
Co_Ini_Marker[j].X = Co_Pnt_Marker[j].X;
Co_Ini_Marker[j].Y = Co_Pnt_Marker[j].Y;
Co_Ini_Marker[j].Z = Co_Pnt_Marker[j].Z;
}
}
//マーカーが正常な値が取得できたかを確認
for(i=1; i<=3; i++){
if(fabs(Co_Ini_Marker[i].X) >= 1.0e+9){
Frag_Err_In = 1;
return(1);
}
}
//************** 原点座標系の回転変換行列Co_RotMatrix作成 ***************************//
//OPTOTRAKのデータ=Z軸方向においたマーカのベクトル
//マーカの配列番号1(原点),2(PA10の座標系のX軸方向),3(PA10の座標系のZ軸方向)です
//X軸が水平に取れているとして全ての軸を計算します
//Co_Ini_MarkerはOPTOTRAKの測定部分のスレッドが10回回った時の軸データ(座標)を保存したものです
//逐次座標系が変わる場合はそのデータを使用します
OPTOTRAK_Z_DATA.X = Co_Ini_Marker[3].X - Co_Ini_Marker[1].X;//0.0;//
OPTOTRAK_Z_DATA.Y = Co_Ini_Marker[3].Y - Co_Ini_Marker[1].Y;//0.0;//
OPTOTRAK_Z_DATA.Z = Co_Ini_Marker[3].Z - Co_Ini_Marker[1].Z;//1.0;//
OPTOTRAK_Y_DATA.X = -(Co_Ini_Marker[2].X - Co_Ini_Marker[1].X);//1.0;//
OPTOTRAK_Y_DATA.Y = -(Co_Ini_Marker[2].Y - Co_Ini_Marker[1].Y);//0.0;//
OPTOTRAK_Y_DATA.Z = -(Co_Ini_Marker[2].Z - Co_Ini_Marker[1].Z);//0.0;//
//YとZを外積してX軸の方向を求める,外積の順序に注意!!
// | I J K |
// Y軸 = | Z.x Z.y Z.z |
// | X.x X.y X.z |
//
// | I J K |
// Z軸 = | X.x X.y X.z |
// | Y.x Y.y Y.z |
//
// | I J K |
// X軸 = | Y.x Y.y Y.z |
// | Z.x Z.y Z.z |
OPTOTRAK_X_DATA.X = (OPTOTRAK_Y_DATA.Y *OPTOTRAK_Z_DATA.Z) -(OPTOTRAK_Y_DATA.Z *OPTOTRAK_Z_DATA.Y);
OPTOTRAK_X_DATA.Y = (OPTOTRAK_Y_DATA.Z *OPTOTRAK_Z_DATA.X) -(OPTOTRAK_Y_DATA.X *OPTOTRAK_Z_DATA.Z);
OPTOTRAK_X_DATA.Z = (OPTOTRAK_Y_DATA.X *OPTOTRAK_Z_DATA.Y) -(OPTOTRAK_Y_DATA.Y *OPTOTRAK_Z_DATA.X);
//Z軸の初期化
OPTOTRAK_Z_DATA.X = 0.0;
OPTOTRAK_Z_DATA.Y = 0.0;
OPTOTRAK_Z_DATA.Z = 0.0;
//Z軸方向の再計算
OPTOTRAK_Z_DATA.X = (OPTOTRAK_X_DATA.Y * OPTOTRAK_Y_DATA.Z) - (OPTOTRAK_X_DATA.Z * OPTOTRAK_Y_DATA.Y);
OPTOTRAK_Z_DATA.Y = (OPTOTRAK_X_DATA.Z * OPTOTRAK_Y_DATA.X) - (OPTOTRAK_X_DATA.X * OPTOTRAK_Y_DATA.Z);
OPTOTRAK_Z_DATA.Z = (OPTOTRAK_X_DATA.X * OPTOTRAK_Y_DATA.Y) - (OPTOTRAK_X_DATA.Y * OPTOTRAK_Y_DATA.X);
//XYZ軸方向に貼り付けたマーカのデータから回転行列を求める
//各軸方向の成分(行ベクトル)が回転行列の積の成分になっている
//回転行列の積を作成する関数
//回転変換行列の作成
ROTATION_MATRIX_CREATE(&OPTOTRAK_X_DATA , &OPTOTRAK_Y_DATA , &OPTOTRAK_Z_DATA);
return(0);
}
//回転変換行列の作成
int Class_OPTOTRACK::ROTATION_MATRIX_CREATE(Cdnt_XYZ *A , Cdnt_XYZ *B , Cdnt_XYZ *C)
{ //X軸 Y軸 Z軸にしたいベクトルの成分
int i , j;
double X_ = 0.0 , Y_ = 0.0 , Z_ = 0.0;
for(i = 0 ; i < 5 ;i++)
{
for(j = 0 ; j < 5 ; j++)
{
Co_RotMatrix[i][j] = 0.0;
}
}//回転行列の初期化,逐次座標系が変わる場合に必要
//各軸ベクトルの絶対値を求める
X_ = Absolute(A);
Y_ = Absolute(B);
Z_ = Absolute(C);
Co_RotMatrix[1][1] = A->X /X_; Co_RotMatrix[1][2] = A->Y /X_; Co_RotMatrix[1][3] = A->Z /X_;
Co_RotMatrix[2][1] = B->X /Y_; Co_RotMatrix[2][2] = B->Y /Y_; Co_RotMatrix[2][3] = B->Z /Y_;
Co_RotMatrix[3][1] = C->X /Z_; Co_RotMatrix[3][2] = C->Y /Z_; Co_RotMatrix[3][3] = C->Z /Z_;
return(0);
}
// 絶対値を返す関数
double Class_OPTOTRACK::Absolute(Cdnt_XYZ *A)
{
double AA;
AA = sqrt(pow(A->X,2.0) + pow(A->Y,2.0) + pow(A->Z,2.0));
return(AA);
}
// マーカーから3次元座標を取得する
int Class_OPTOTRACK::Co_Get_OptoData(int Num)
{
int i;
if ( DataGetLatest3D( &uFrameNumber, &uElements, &uFlags, &p3dData[0] ) )
Co_longOR_EXIT();
//マーカーのOptotrak座標系から見た3次元座標を取得
for(i=Num; i<Num+NUM_CTRL_MARKERS; i++){
Co_Pnt_Marker[i].X = (double)p3dData[i-1].X;
Co_Pnt_Marker[i].Y = (double)p3dData[i-1].Y;
Co_Pnt_Marker[i].Z = (double)p3dData[i-1].Z;
}
//マーカーが正常な値が取得できたかを確認(できていなければErrNumberにマーカーナンバーを取得)
for(i=Num; i<Num+NUM_CTRL_MARKERS; i++){
if(fabs(Co_Pnt_Marker[i].X) >= 1.0e+9){
Frag_Err_Mi = 1;
return(1);
}
}
//原点位置を基準にしたMARKERの位置ベクトル(4)
for(i=Num; i<Num+NUM_CTRL_MARKERS; i++)
{
Co_OptoDataR[i].X = Co_Pnt_Marker[i].X - Co_Ini_Marker[1].X;
Co_OptoDataR[i].Y = Co_Pnt_Marker[i].Y - Co_Ini_Marker[1].Y;
Co_OptoDataR[i].Z = Co_Pnt_Marker[i].Z - Co_Ini_Marker[1].Z;
}
return(0);
}
// Optotrakの生データの座標変換を行う
int Class_OPTOTRACK::Cro_Rotation_Function(XYZ A, XYZ *B)
{
//ローカル変数の宣言
int i , j;
double C[3] , D[3];
//変数の初期化および数値の代入
for(i = 0 ; i <= 2 ; i++){
C[i] = 0.0;
D[i] = 0.0;
}
C[0] = A.X;
C[1] = A.Y;
C[2] = A.Z;
//マーカの原点に取ったデータを回転変換する
for(i = 0 ; i <= 2 ; i++){
for(j = 0 ; j <= 2 ; j++)
D[i] += Co_RotMatrix[i+1][j+1] * C[j]; //ここの掛け算はiとjに気を付ける
}
//回転変換後のデータを戻す
B->X = D[0];
B->Y = D[1];
B->Z = D[2];
return(0);
}
// データの読み込みを終了させる(エラー関数)
int Class_OPTOTRACK::Co_longOR_EXIT()
{
//8. De-activate the IRED markers.
OptotrakDeActivateMarkers();
//10. Disconnect the PC application program from the transputer system.
TransputerShutdownSystem();
return(0);
}