/*! \file main.c \brief ランダムに配置される車庫にビーゴを駐車するプログラム \ Created on: 2011/04/18 Author: ksato \ Modified on:2011/04/24 Author: fukuda $Id: main.c xxxx 2011/04/24 19:57:30Z fukuda$ */ /* ライブラリ */ #include // printfなどの入出力関数 #include // mallocとfreeやexitなど #include // signal #include // 数学関数 #include "scip2awd.h" // AWDのURGライブラリ #include // spur用ライブラリ #include // opengl用ライブラリ //マクロ定義 #if !defined(GLUT_WHEEL_UP) # define GLUT_WHEEL_UP 3 # define GLUT_WHEEL_DOWN 4 #endif #define RAD(deg) ((deg)*M_PI/180) #define MAXPOINTS 1000 /* 記憶する点の数   */ /* 外部変数 */ S2Port *urgPort; // デバイスファイル名 S2Sdd_t urgBuf; // データを確保するバッファ S2Scan_t *urgData; // バッファへのポインタ S2Param_t urgParam; // URGのパラメータを確保 GLint point[MAXPOINTS][2]; /* 座標を記憶する配列 */ int pointNum = 0; /* 記憶した座標の数  */ int near = 1, far = 1; static int x, y; int i, ret; double rad; double scanArea = RAD(239.77); double selfArea = RAD(300.33); int gShutoff; /*! \ func : display \ brief: ウィンドウ描画 */ void display(void) { double x_pos0, y_pos0; double x_pos, y_pos; glClear(GL_COLOR_BUFFER_BIT); glColor3d(1.0, 1.0, 1.0); /* 測位データの取り出し*/ ret=S2Sdd_Begin(&urgBuf, &urgData); if(ret > 0) { for(i=0; i < urgData->size; i++) { x_pos0 = ( x + (double)urgData->data[i] ) * sin(rad); y_pos0 = ( y + (double)urgData->data[i] ) * cos(rad); x_pos = ( -x_pos0*cos(-selfArea) - y_pos0*sin(-selfArea)); y_pos = ( x_pos0*sin(-selfArea) - y_pos0*cos(-selfArea)); if ( urgData->data[i] > 60 && urgData->data[i] < 4000 ) { glColor3d(1.0, 0.0, 0.0); glPointSize(8.0); glBegin(GL_POINTS); rad = (double)(urgParam.step_min + i - urgParam.step_front)/urgData->size*scanArea; /*printf("%d\t%d\t%f\t%f\n", i+44, (int)urgData->data[i], x_pos, y_pos); */ glVertex2d( x_pos, y_pos ); glEnd(); glColor3d(0.0, 0.0, 1.0); glLineWidth(8.0); glBegin(GL_LINES); glVertex2d( -60.0*sin(rad), 60.0*cos(rad) ); glVertex2d( x_pos, y_pos ); glEnd(); } } glutSwapBuffers(); S2Sdd_End(&urgBuf); // アンロック(読み込み終了) } else if (ret == -1) { fprintf( stderr, "ERROR: Fatal error occurred.\n" ); } else usleep(100); // 測位データがロック中(書込中) glutPostRedisplay(); } /*| \func : resize \brief: ウィンドウスクリーン */ void resize(int w, int h) { glViewport(0, 0, w, h); glLoadIdentity(); glOrtho( -5000.0, 5000.0, -5000.0, 5000.0, -(double)near, (double)far ); /* 点の大きさをスクリーンの幅に比例させる */ glPointSize((float)w * 0.1f); } /*! \func : polarView \brief: 視点を変える関数 */ void polarView(double distance, double twist, double elevation, double azimuth) { glTranslated(0.0, 0.0, -distance); glRotated(-twist, 0.0, 0.0, 1.0); glRotated(-elevation, 1.0, 0.0, 0.0); glRotated(-azimuth, 0.0, 1.0, 0.0); } /*! \func : keyboard \brief: キー設定 */ static void keyboard(unsigned char key, int x, int y) { switch (key) { case 'p': polarView( 2000.0, 0.0, 30.0, 0.0 ); break; case 'q': case 'Q': case '\033': /* ESC か q か Q をタイプしたら終了 */ exit(0); default: break; } } /*! \func : init \brief: 初期設定 */ static void init(void) { /* 初期設定 */ glClearColor(1.0, 1.0, 1.0, 1.0); /* 点にアンチエリアシング処理を行う */ glEnable(GL_POINT_SMOOTH); /* アンチエリアシング処理の品質を最高にする */ glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); } /*! \ func : ctrlc \ brief: シグナルハンドラの設定.Ctrl+Cでプログラムを終了させる */ void ctrlC(int aStatus) { signal(SIGINT, NULL); /* URGの測位停止 */ ret = Scip2CMD_StopMS( urgPort, &urgBuf ); if( ret == 0 ) { fprintf( stderr, "ERROR: StopMS failed.\n" ); exit( 0 ); } printf( "Stopped\n" ); /* バッファの解放 */ S2Sdd_Dest( &urgBuf ); printf( "Buffer destructed\n" ); /* ポートを閉じる */ Scip2_Close( urgPort ); printf( "Port closed\n" ); exit( aStatus ); } /*! \func : setctrlC \brief: ctrlCを呼び出す関数 */ void setctrlC( ) { signal( SIGINT, ctrlC ); } /*! \func :main \brief :メインプログラム */ int main( int aArgc, char **aArgv ) { int cnt = 0; /* OpenGL設定 */ glutInitWindowPosition(50, 50); glutInitWindowSize(700, 500); glutInit(&aArgc, aArgv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); glutCreateWindow(aArgv[0]); glutDisplayFunc(display); glutReshapeFunc(resize); glutKeyboardFunc(keyboard); init(); gShutoff = 0; aArgv[1] = "/dev/ttyACM0"; // デバイス認識 setctrlC( ); // シグナルハンドラの設定 /**********************spur関連****************************/ Spur_init( ); // 初期化 Spur_set_vel( 0.15 ); // 最大速度0.15m/sに設定 Spur_set_accel( 1.0 ); // 加速度1.0m/sに設定 Spur_set_angvel( 0.25 ); // 最大角速度0.25rad/sに設定 Spur_set_angaccel( 2.0 ); // 各加速度2.0rad/ssに設定 Spur_set_pos_GL( 0, 0, 0 ); // スタート地点を原点にGL座標を設定 /*********************************************************/ /**********************URG関連****************************/ /* ポートオープン */ urgPort = Scip2_Open( aArgv[1], B115200 ); //デバイス名,ボーレート設定 if ( urgPort == 0 ) { fprintf( stderr, "ERROR: Failed to open device.\n" ); return 0; } printf( "Port opened\n" ); /* バッファの初期化 */ S2Sdd_Init( &urgBuf ); printf( "Buffer initialized\n" ); /* URGパラメータの読み出し */ Scip2CMD_PP( urgPort, &urgParam ); /* 垂れ流しモードの開始 */ Scip2CMD_StartMS( urgPort, urgParam.step_min, urgParam.step_max, 1, 0, 0, &urgBuf, SCIP2_ENC_2BYTE ); Spur_line_GL( 0, 0, 0 ); // 直進 while ( !gShutoff ) { /* 測位データの取り出し */ ret = S2Sdd_Begin( &urgBuf, &urgData ); cnt++; if ( cnt == 1 ) printf( "\nAcquring sencing data Until obstacles approach ...\n\n" ); if ( ret > 0 ) { /* 最初の壁検出からポールへ、その後、車庫?の壁までの移動 */ if ( urgData -> data[urgParam.step_front] <= 500 ) { printf("\nNow Checking ...\n\n"); Spur_free( ); usleep( 100000 ); Spur_spin_GL( - M_PI / 2.0 ); while ( !Spur_near_ang_GL( - M_PI / 2.0, 0.1 ) ) printf("SPIN_GL -> NEAR_ANG_GL\n"); Spur_orient_FS( 0 ); Spur_set_pos_LC( 0, 0, 0 ); while ( (urgData -> data[urgParam.step_front*(int)sin(1.5)]) < 500 ) { if( Spur_near_pos_LC( 0.45, 0, 0 ) ) { Spur_free( ); usleep(1000000); Spur_spin_GL( - M_PI / 2.0 ); while ( !Spur_near_ang_GL( - M_PI, 1.0 ) ) printf("SPIN_GL -> NEAR_ANG_GL\n"); Spur_orient_FS( 0 ); } } } /* 左と前に壁がある環境からの車庫?までの移動 */ else if ( urgData -> data[urgParam.step_front*(int)sin(1.5)] <= 5000 && urgData -> data[urgParam.step_front] <= 500 ) { Spur_free( ); usleep( 1000000 ); Spur_spin_GL( - M_PI / 2.0 ); while ( !Spur_near_ang_GL( - 3.0 * M_PI / 2.0, 0.1 ) ) printf("SPIN_GL -> NEAR_ANG_GL\n"); Spur_set_pos_LC( 0, 0, 0 ); usleep( 1000000 ); Spur_orient_FS( 0 ); /* 車庫①判定 */ while ( !Spur_stop_line_LC( 1.5, 0, 0.1 ) ) printf("ORIENT_FS -> STOP_LINE_LC\n"); Spur_free( ); usleep( 1000000 ); Spur_circle_LC( 1.5, 0.45, 0.1 ); while ( !Spur_near_ang_LC( M_PI, 0.1 ) ) printf("CIRCLE_LC -> NEAR_ANG_LC\n"); Spur_free( ); usleep( 1000000 ); Spur_orient_FS( 0 ); } /* 車庫①or②判定 */ else if ( urgData -> data[urgParam.step_front] < 300 && urgData -> data[urgParam.step_front*(int)cos(1.5)] < 300 ) { if( urgData -> data[urgParam.step_front*(int)cos(1.5)] < 300 || urgData -> data[urgParam.step_front*(int)sin(1.5)] < 300 ) { Spur_stop( ); gShutoff = 1; usleep( 100 ); } } S2Sdd_End( &urgBuf ); // アンロック(読み込み終了) } else if ( ret == - 1 ) { fprintf( stderr, "ERROR: Fatal error occurred.\n" ); } else usleep( 100 ); // 測位データがロック中(書込中) } glutMainLoop(); ret = Scip2CMD_StopMS( urgPort, &urgBuf ); // URGの測位停止 if( ret == 0 ) { fprintf( stderr, "ERROR: StopMS failed.\n" ); return 0; } printf( "Stopped\n" ); S2Sdd_Dest( &urgBuf ); // バッファの解放 printf( "Buffer destructed\n" ); Scip2_Close( urgPort ); // ポートを閉じる printf( "Port closed\n" ); //glutMainLoop(); // opengl 無限ループ return 0; }