/* * ***************************************************************** * * * * * Copyright (c) Fast Corporation, 1997 * * * * * * All Rights Reserved. Unpublished rights reserved under * * * the copyright laws of the Japan. * * * * * * The software contained on this media is proprietary to * * * and embodies the confidential technology of Fast * * * Corporation. Possession, use, duplication or * * * dissemination of the software and media is authorized only * * * pursuant to a valid written license from Fast Corporation. * * * * * ***************************************************************** */ /* CSC90X 円周上付近の平均濃度検査 CIRCAVE2.C */ /*[作成者]H.Yagi */ /* 目的: 関数: 履歴: Ver 1.0 97/08/14 Ver 1.1 99/04/07 GUIの一部変更 S.Masuda 注記:m_menu.hをインクルードして下さい。 m_menu.c及びm_note.cをリンクして下さい。 */ /* * Include compiler runtime library */ #include #include /* * Include CSC90X library */ #include "f_stdlib.h" #include "f_time.h" #include "f_gui.h" #include "f_stdio.h" #include "f_graph.h" #include "f_image.h" #include "f_pinf.h" #include "f_video.h" #include "f_system.h" #include "f_math.h" #include "f_search.h" #include "f_file.h" /* * Include CSC90X common local */ #include "m_menu.h" /* * プロトタイプ宣言 */ void main( void ); void main_menu_disp( void ); void disp_help( void ); void param_set( void ); void gs_set( int, int, PARADIGM * ); void wind_set( int *, int *, int *, int * ); void ptn_reg( void ); void ptn_disp( void ); void gs_joken( void ); void search_ctrl( int ); int search_exec( int, int, int, int, int, int, int, int, int, int ); void set_en( int, int, PARADIGM * ); void exec_kijun( int, int, PARADIGM * ); void exec( void ); int d4i5_d( double ); void draw_cros( int, int ); void draw_batu( int, int, int ); void calib( double, double, double, double, double, int *, int * ); void average( int, int, int, int, int * ); void set_file( int, int, PARADIGM * ); void xxx_freeze( int ); void cut_space( char *, char * ); extern int message_note( void ); /* * メニュー項目 */ #define LANG_N 2 #define MAIN_MENU_N 4 static const char *str_main_menu[MAIN_MENU_N][LANG_N] = { { " SET ", " 設 定 " }, { " EXEC ", " 実 行 " }, { " PROC3 ", " 処理3 " }, { " PROC4 ", " 処理4 " } }; #define INIT_CUR_POS_X 255 #define INIT_CUR_POS_Y 239 typedef enum { SEARCH_KIJUN, SEARCH_WORK } dummy1; #define FILENAME_SAIZE 12 char grayfile[FILENAME_SAIZE+1]; #define MAX_NO_GRAY_SEARCH 50 static int Rslt_Buf[(MAX_NO_GRAY_SEARCH * 3)]; int pad_level; int pad_level_ptn; PVAL value[7]; static char ss[70]; int sts; int xs, ys, xe, ye; int time; int no; static double dx, dy, dr; int cx, cy; static double base_x, base_y; static int master_ave[360]; int name; /*サーチパタン名称 */ int gs_wxs; /* サーチ範囲始点X */ int gs_wys; /* サーチ範囲始点Y */ int gs_wxe; /* サーチ範囲終点X */ int gs_wye; /* サーチ範囲終点Y */ int seido; /* 精度 */ int complex; /* 複雑度 */ int mid_lower; /* 途中下限値 */ int last_lower; /* 最終下限値 */ int kensa_r; /*検査半径 */ int kensa_pitch; /*検査角ピッチ */ int shikii; /*許容値レベル±*/ int fs0_image_sw; /*FS0画像入力スイッチ*/ int master_x, master_y; int ofs_x, ofs_y; /* * メイン */ void main( void ) { int sts; int xpos; int ypos; int s_xpos; int s_ypos; /* 初期メッセージ表示 */ if( NORMAL_RETURN != message_note() ) return; /* パラメタ初期化 */ xpos = INIT_CUR_POS_X; ypos = INIT_CUR_POS_Y; s_xpos = INIT_CUR_POS_X; s_ypos = INIT_CUR_POS_Y; name = 0x31303030; /* 0001 */ gs_wxs = 0; gs_wys = 0; gs_wxe = 511; gs_wye = 479; seido = 0; complex = 1; mid_lower = 5000; last_lower = 7000; kensa_r = 5; /*検査半径 */ kensa_pitch = 30; /*検査角ピッチ */ shikii = 30; /*許容値レベル±*/ fs0_image_sw = OFF; strcpy( grayfile, "GRAYMEM1.DAT" ); /*FS0画像ファイル名*/ /* 入力ビデオ制御 */ Lib_input_video_control( GRAY_PLANE ); /* ビデオ出力表示項目制御 */ Lib_display_control( GRAY_PLANE | LINE_PLANE | CHAR_PLANE ); /* ビデオ表示項目クリア */ Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); /* カーソル初期化 */ Lib_init_cursor(); /* メインメニューの表示 */ main_menu_disp(); /* マウスカーソルの表示 */ Lib_draw_cursor( INIT_CUR_POS_X, INIT_CUR_POS_Y ); /* メニュー制御 */ for (;;) { sts = 0; /* マウス位置読みとり */ sts = Lib_see_current_position( &xpos, &ypos ); if ( s_xpos != xpos || s_ypos != ypos ) { /* マウス表示位置移動 */ Lib_move_cursor( xpos, ypos ); s_xpos = xpos; s_ypos = ypos; } /* 処理振り分け */ if ( CURSOR_EXECUTE == sts ) { if ( xpos > MENU_1_XS && xpos < MENU_1_XE && ypos > MENU_1_YS && ypos < MENU_1_YE ) { Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); param_set(); /*設定*/ Lib_move_cursor( xpos, ypos ); main_menu_disp(); } else if ( xpos > MENU_2_XS && xpos < MENU_2_XE && ypos > MENU_2_YS && ypos < MENU_2_YE ) { Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); exec(); /*実行*/ Lib_move_cursor( xpos, ypos ); main_menu_disp(); } else if ( xpos > MENU_H_XS && xpos < MENU_H_XE && ypos > MENU_H_YS && ypos < MENU_H_YE ) { Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); disp_help(); /* ヘルプ */ Lib_move_cursor( xpos, ypos ); main_menu_disp(); } else if ( xpos > MENU_E_XS && xpos < MENU_E_XE && ypos > MENU_E_YS && ypos < MENU_E_YE ) { break; /* 終了 */ } } } } /* * メインメニュー表示 */ static void main_menu_disp( void ) { int iLanguage; /* 日本語/英語表示文字列切替情報取得 */ iLanguage = Lib_get_disp_language(); /* 整列キー表示 -> ( m_menu.c ) */ SUB_menu_disp4he( (char *)str_main_menu[0][iLanguage], (char *)str_main_menu[1][iLanguage], (char *)NULL, (char *)NULL ); } /* * ヘルプ表示 */ static void disp_help( void ) { Lib_chrdisp( 10, 8, "【機能\概要】       CIRCAVE2" ); Lib_chrdisp( 11, 10, "円周上付近の平均濃度を求め検査します。" ); Lib_chrdisp( 11, 12, "アライメント機能\付き。" ); Lib_chrdisp( 11, 14, "FS0画像入力も可です。" ); } /*********************************************************************/ /*  設定                         */ /*********************************************************************/ void param_set() { pad_level = Lib_view_open(); Lib_view_set_title( pad_level, "設定" ); Lib_view_set_null ( pad_level, 5, 5, "アライメント", 0 ); Lib_view_set_null ( pad_level, 5, 35, "近似円設定", 1 ); Lib_view_set_uniq_numeral( pad_level, 5, 65, "検査半径" , kensa_r, 1, 50, 2 ); Lib_view_set_uniq_numeral( pad_level, 5, 95, "検査角ピッチ", kensa_pitch, 1, 360, 3 ); Lib_view_set_null ( pad_level, 5, 125, "基準計測", 4 ); Lib_view_set_uniq_numeral( pad_level, 5, 155, "許容値 ±" , shikii, 0, 100, 5 ); Lib_view_set_uniq_alter ( pad_level, 5, 185, "FS0画像", fs0_image_sw, 6 ); Lib_set_paradigm( pad_level, 0, START_TIMING, gs_set ); Lib_set_paradigm( pad_level, 1, START_TIMING, set_en ); Lib_set_paradigm( pad_level, 4, START_TIMING, exec_kijun ); Lib_set_paradigm( pad_level, 6, END_TIMING, set_file ); Lib_view_set_size( pad_level, 50, 80, 5, 5 ); Lib_draw_menu( pad_level ); if( PAD_EXECUTE == Lib_process_menu( pad_level, value ) ) { kensa_r = value[2].value_type; kensa_pitch = value[3].value_type; shikii = value[5].value_type; fs0_image_sw = value[6].on_off_type; } Lib_erase_menu( pad_level ); Lib_view_close( pad_level ); } /************************************************************************/ /* 近似円設定 */ /************************************************************************/ void set_en( Timing, Numb, val ) int Timing; int Numb; PARADIGM val[]; { POINT_T point[32]; int sts, rtn; int xpos; int ypos; int s_xpos; int s_ypos; int cnt; Lib_erase_menu( pad_level ); if ( OFF == value[6].on_off_type ) Lib_freeze( NOT_TRANSMIT ); else xxx_freeze( TRANSMIT ); xpos = 255; ypos = 240; cnt = 0; Lib_chrdisp( 1, 1, "近似円を求めるための座標を指定してください(3〜15点)" ); for (;;) { sts = 0; sts = Lib_see_current_position( &xpos, &ypos ); /* マウス位置読みとり */ if ( s_xpos != xpos || s_ypos != ypos ) { Lib_move_cursor( xpos, ypos ); s_xpos = xpos; s_ypos = ypos; } if ( CURSOR_EXECUTE == sts ) { point[cnt].x = xpos; point[cnt].y = ypos; Lib_pset( xpos, ypos, 1 ); cnt++; if ( 15 < cnt ) break; } else if ( CURSOR_CANCEL == sts ) { if ( cnt < 3 ) Lib_display_message( 70, 200, "CANCEL err!", "3点以上のドット設定が必要です。" ); else break; } } Lib_chrdisp( 1, 1, "                            " ); rtn = Lib_fcalcircl( cnt, point, &dx, &dy, &dr ); if ( NORMAL_RETURN != rtn ) { Lib_sprintf( ss, "Lib_fcalcircl ERR! ( rtn = %d )", rtn ); Lib_chrdisp( 1, 30, ss ); } else { cx = d4i5_d( dx ); cy = d4i5_d( dy ); /* 円の表示 */ Lib_drawcircle( cx, cy, d4i5_d( dr ) ); } /* 円周基点算出 */ base_x = dx; base_y = dy - dr; Lib_draw_menu( pad_level ); } /*********************************************************************/ /* 基準レベル計測                 */ /*********************************************************************/ void exec_kijun( Timing, Numb, val ) int Timing; int Numb; PARADIGM val[]; { int i, a; int ix, iy; int mem_no; Lib_erase_menu( pad_level ); if ( OFF == value[6].on_off_type ) Lib_freeze( NOT_TRANSMIT ); else xxx_freeze( TRANSMIT ); search_ctrl( SEARCH_KIJUN ); /*アライメントマークのサーチ*/ /* 1点目 */ Lib_drawcircle( base_x, base_y, kensa_r ); /* 位置表示 */ mem_no = 0; average( mem_no, base_x, base_y, kensa_r, &master_ave[0] ); Lib_sprintf( ss, "%d", master_ave[0] ); Lib_kanjishift( 0, 0, 0, base_x+10, base_y+10, ss ); /* 2点目以降 */ for ( i=kensa_pitch, a=1; i<360; i=i+kensa_pitch, a++ ) { /* 座標変換 */ calib( base_x, base_y, dx, dy, i, &ix, &iy ); /* 位置表示 */ Lib_drawcircle( ix, iy, kensa_r ); /* 平均濃度算出 */ mem_no = 0; average( mem_no, ix, iy, kensa_r, &master_ave[a] ); Lib_sprintf( ss, "%d", master_ave[a] ); Lib_kanjishift( 0, 0, 0, ix+10, iy+10, ss ); } Lib_display_keyinput( 430, 0, " 確認 " ); Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); Lib_freerun(); Lib_draw_menu( pad_level ); } /*********************************************************************/ /* 実行                 */ /*********************************************************************/ void exec() { int i, a; int ix, iy; int mem_no; int ave; double wbase_x, wbase_y; double wdx, wdy; Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); if ( OFF == fs0_image_sw ) Lib_freeze( NOT_TRANSMIT ); else xxx_freeze( TRANSMIT ); /**/Lib_strtclk_count(); /*タイマーカウントモードのスタート*/ search_ctrl( SEARCH_WORK ); /*アライメントマークのサーチ*/ /* 1点目 */ wbase_x = base_x + ofs_x / 10.0; wbase_y = base_y + ofs_y / 10.0; Lib_drawcircle( wbase_x, wbase_y, kensa_r ); /* 位置表示 */ mem_no = 0; average( mem_no, wbase_x, wbase_y, kensa_r, &ave ); /* しきい値チェック */ if ( (ave < master_ave[0] - shikii) || (master_ave[0] + shikii < ave) ) draw_batu( wbase_x, wbase_y, kensa_r-2 ); Lib_sprintf( ss, "%d", ave ); Lib_kanjishift( 0, 0, 0, wbase_x+10, wbase_y+10, ss ); /* 2点目以降 */ for ( i=kensa_pitch, a=1; i<360; i=i+kensa_pitch, a++ ) { /* 座標変換 */ wdx = dx + + ofs_x / 10.0; wdy = dy + + ofs_y / 10.0; calib( wbase_x, wbase_y, wdx, wdy, i, &ix, &iy ); /* 位置表示 */ Lib_drawcircle( ix, iy, kensa_r ); /* 平均濃度算出 */ mem_no = 0; average( mem_no, ix, iy, kensa_r, &ave ); /* しきい値チェック */ if ( (ave < master_ave[a] - shikii) || (master_ave[a] + shikii < ave) ) draw_batu( ix, iy, kensa_r-2 ); Lib_sprintf( ss, "%d", ave ); Lib_kanjishift( 0, 0, 0, ix+10, iy+10, ss ); } Lib_time_disp( 0, 452 ); Lib_display_keyinput( 460, 0, "確認" ); Lib_cls( ( LINE_PLANE | CHAR_PLANE ), BLACK_COLOR ); Lib_freerun(); } /***********************************************************************/ /* 入力数値(double)の4捨5入した数値(int)を返す */ /***********************************************************************/ int d4i5_d( double in ) { int out; if ( in >= 0.0 ) out = (int)( in + 0.5 ); else out = (int)( in - 0.5 ); return( out ); } /************************************************************************/ /* クロスマーク表示 */ /************************************************************************/ void draw_cros( x, y ) int x, y; { Lib_drawline( x-8, y, x+8, y ); Lib_drawline( x, y-8, x, y+8 ); } /************************************************************************/ /* ×マーク表示 */ /************************************************************************/ void draw_batu( x, y, size ) int x, y; /* 入力:表示位置 */ int size; { Lib_drawline( x-size, y-size, x+size, y+size ); Lib_drawline( x-size, y+size, x+size, y-size ); } /************************************************************************/ /* 座標変換 */ /************************************************************************/ void calib( base_x, base_y, cx, cy, angle, ix, iy ) double base_x, base_y; /*基点*/ double cx, cy; /* 回転中心 */ double angle; /* 回転角度degree */ int *ix, *iy; { double pi, phi; double cos_phi, sin_phi; double xx, yy; pi = 4.0*atan( 1.0 ); /* PAI(3.14159)の算出 */ phi = angle * pi / 180.0; cos_phi = cos( phi ); sin_phi = sin( phi ); xx = (base_x-cx) * cos_phi - (base_y-cy) * sin_phi; yy = (base_x-cx) * sin_phi + (base_y-cy) * cos_phi; xx = xx + cx; yy = yy + cy; *ix = d4i5_d(xx); *iy = d4i5_d(yy); } /************************************************************************/ /* 平均濃度算出 */ /************************************************************************/ void average( mem_no, ix, iy, kensa_r, ave ) int mem_no, ix, iy, kensa_r; int *ave; { register int i, a; char *base; char *wbase; char *wb2; int xs, ys, xe, ye; int s_xs; int windx; int windy; int sum; int cnt; xs = ix - kensa_r; ys = iy - kensa_r; xe = ix + kensa_r; ye = iy + kensa_r; s_xs = xs; windx = xe - xs + 1; /* ウィンド枠x画素数 */ windy = ye - ys + 1; /* ウィンド枠y画素数 */ base = Lib_adrs_gray_memory( mem_no ); wbase = base + 512*ys + xs; sum = cnt = 0; for ( i=0; i