31 สิงหาคม 2553

ทดลองการว๊าบครั้งที่ 5

ข้อดี

Warp ตำแหน่งได้ถูกต้องทั้ง แกน X และ แกน y

ต้องปรับปรุง

การใช้ wiimote 2 ตัวตอบสนองได้ช้าลง

อาจแก้ไขการคำนวณการ Warp ใหม่ให้เร็วขึ้น โดยตัดแกนที่ไม่ได้ใช้ออกไป

แยกการอ่านค่าออกเป็น 2 Thread สำหรับ wiimote แต่ละตัว

ทดลองการว๊าบครั้งที่ 4

ทดสอบการว๊าบโดยเลื่อนกล้องกับโปรเจคเตอร์ในแกน Y

จะทำให้ตำแหน่งในแกน X ได้ถูกต้อง

งานที่จะทำต่อ

ใช้ wiimote 2 ตัวทำการว๊าบทั้ง 2 แกนจะทำให้

คำนวนตำแหน่งได้ถูกต้องในขณะที่เลื่อนระยะเข้าใกล้โปรเจคเตอร์

28 สิงหาคม 2553

ทดลองการว๊าบครั้งที่ 3

เปลี่ยน

1. เปลี่ยนอัลกอรึทึมที่ใช้ว๊าบ มีความเที่ยงตรงแต่ช้ากว่าแบบที่ใช้ในการทดลองครั้งที่

ปัญหาเดิมที่ยังไม่ได้แก้ไข

1.ติดปัญหาเรื่องการตอบสนอง ที่ยังช้าอยู่

แนวทางการแก้ไข

1. ใช้ 1 Thread ในการอ่านค่าจาก wiimote

2. ใช้ 1 Thread ในการ display ทางจอภาพ

 

แก้ปัญหาเรื่องมุม FOV ของ wiimote และโปรเจคเตอร์ ด้วยฐานตั้ง Wiimote และ โปรเจคเตอร์

ฐานตั้งนี้สามารถปรับมุมเอียงระหว่าง wiimote กับ โปรเจคเตอร์ได้

โดยด้านล่างมีไม้แผ่นใหญ่ติดแทปตีนตุ๊กแกไว้

และด้านล่างของwiimote และ  โปรเจคเตอร์ ก็ติดแทปตีนตุ๊กแกไว้เหมือนกัน


ทดลองการว๊าบครั้งที่ 2

พัฒนา

1.แก้มุม FOV ระหว่าง Wiimote กับ โปรเจคเตอร์ ด้วยฐานตั้งปรับมุมได้

ปัญหาใหม่

1.ติดปัญหาเรื่องการตอบสนอง

2.การวาบไม่ตรงในแนวแกน x ประมาณ 3 เซนติเมตร

27 สิงหาคม 2553

หามุม FOV ของ wiimote

 

ทดสอบทั้งหมด 2 ครั้ง

ได้ค่าต่างๆนำไปคำนวณด้วย Matlab ดังนี้

clc; clear all; close all;
%% Data 1
% fovy height
height = (28.0 + 30.0)/2;
Zprp = 0;
Zvp = 57;
fovyH = rad2deg(atan(height/2/Zvp))*2

% fovy width
width = (43.0 + 42.0)/2;
Zprp = 0;
Zvp = 57;
fovyW = rad2deg(atan(width/2/Zvp))*2

%% Data 1
% fovy height
height = (23.0 + 22.5 )/2;
Zprp = 0;
Zvp = 40;
fovyH = [fovyH rad2deg(atan(height/2/Zvp))*2]

% fovy width
width = (30.2 + 30.0)/2;
Zprp = 0;
Zvp = 40;
fovyW = [fovyW rad2deg(atan(width/2/Zvp))*2]

%% Fovy Average
mean(fovyH)
mean(fovyW)

FOV ด้าน Height = 30 องศา

FOV ด้าน Width = 41 องศา

จึงสรุปได้ว่า FOV ไม่ใช่ปัญหาที่ทำให้การว๊าบไม่สำเร็จ

ทดลองการว๊าบครั้งที่ 1

 

คาดว่าสาเหตุน่าจะมาจากการที่มุม FOV ของ Wiimote น้อยกว่ามุม FOV ของ โปรเจคเตอร์

ภาพที่ได้จึงไม่ครอบคลุม

 

เพื่อทดสอบสมมติฐานนี้ จึงต้องทำการหา มุม FOV ของ Wiimote

26 สิงหาคม 2553

YAMOROBOCON2010

ขอประชาสัมพันธ์โครงการและขอเชิญสมัครเข้าร่วมแข่งขันหุ่นยนต์ YAMOROBOCON2010

ทั้งนี้ สามารถติดตามรายละเอียดข่าวสารและสมัครเข้าร่วมการแข่งขันได้ที่

http://www.yamorobocon.com

การคำนวณพิกัด 2D หรือระนาบ เมื่อกำลังใช้งานพิกัด 3D ใน OpenGL แบบ Perspective Projection

การคำนวณพิกัด 2D หรือระนาบ เมื่อกำลังใช้งานพิกัด 3D ใน OpenGL แบบ Perspective

เมื่อเราตั้งค่า Projection Matrix เป็น 3D แบบ Perspective แล้ว

เรายังสามารถใช้การวาดรูปแบบ 2D ได้โดยสามารถคำนวณหา

ความกว้าง ความสูง และ พิกัดของ 2D ได้จาก Code การ Projection

glMatrixMode (GL_PROJECTION);                                    //set the matrix to projection
    glLoadIdentity ();
    gluPerspective (30.32, 4.0/3.0, 50.0, 300.0);               //set the perspective (angle of sight, width/height, near, far   )

และอีกค่าหนึ่งที่นำมาคิดคือ มุมมองของกล้อง

/*
* camera position, x,y,z, looking at x,y,z, Up Positions of the camera
*/
gluLookAt
(
    0.0, 0.0, 110.0,/* camera */
    0.0, 0.0, 0.0,    /* lens towards */
    0.0, 1.0, 0.0   /* up-vector */
);

จาก Code ข้างบนเราจะได้คำนวนหา

ขอบเขตความกว้าง [XWmin, XWmax]

ขอบเขตความยาว [YWmin, YWmax]

ได้ดังนี้

fovyH = 30.32;
aspect = 4/3;
Zvp = 110;
Zprp = 0;

height = 2 * Zvp * tan(deg2rad(fovyH/2));
YWmin = Zprp - height/2
YWmax = Zprp + height/2

width = aspect * height;
XWmin = Zprp - width/2
XWmax = Zprp + width/2

การคำนวณหามุม Fovy ของ 3M Projector Parameter

สูตรในการคำนวณมุม หามาจากหนังสือ Computer Graphics with OpenGL ของ Hearn Baker สำนักพิมพ์ Pearson Prentice Hall

หน้า 375

tan(theta/2) = (height/2) / (Zprp – Zvp)

theta คือ fovy angle นั่นเอง

height คือ ความสูงของภาพที่ฉายออกไป

Zprp คือ ค่า Z ของกล้อง

Zvp คือ ค่า Z ของ View Plane

ดังนั้น Zprp – Zvp ก็คือ ระยะห่างระหว่างกล้องกับ View Plane นั่นเอง

ในที่นี้กล้องคือโปรเจคเตอร์

ผลการวัด ครั้งที่ 1

height ทั้งสองข้างของภาพ = 35.5 cm และ 36.13 cm

Zprp – Zvp  = 72.4 cm

fovy angle = 27.6550

ผลการวัด ครั้งที่ 2

height ทั้งสองข้างของภาพ = 15.4 cm และ 15.5 cm

Zprp – Zvp  = 30.4 cm

fovy angle = 28.5155

ดังนั้นมุม Fovy โดยเฉลี่ยคือ 28 องศา

 

21 สิงหาคม 2553

คลาสวาบจากสีเหลี่ยมด้านไม่เท่า ไปยังสีเหลี่ยมด้านไม่เท่า Nemin c++ warping class

คลาสวาบจากสีเหลี่ยมด้านไม่เท่า ไปยังสีเหลี่ยมด้านไม่เท่า Nemin c++ warping class
เขียนขึ้นมาจากหลัก Inferring Projective Mappings
ในหนังสือ Fundamentals of Texture Mapping and Image Warping
อ่านเรื่องการ Warp ได้เพื่อจะได้เข้าใจมากขึ้น
ในที่นี้คือการเขียนโค้ดด้วยภาษา C++ หลังจากที่มี
เวอร์ชั่น Matlab ไปแล้ว
ตัวอย่างการเรียกใช้งาน

        /* source quadrilateral
         */
        int u0, u1, u2, u3, v0, v1, v2, v3;
        u0 = 7;
        v0 = 171;
        u1 = 294;
        v1 = 168;
        u2 = 307;
        v2 = 2;
        u3 = 1;
        v3 = 2;

        /* destination quadrilateral
         */
        int x0, x1, x2, x3, y0, y1, y2, y3;
        x0 = 10;
        y0 = 190;
        x1 = 310;
        y1 = 190;
        x2 = 310;
        y2 = 10;
        x3 = 10;
        y3 = 10;
       
        /* Set Warp parameter
         * for making transformation matrix
         */
        CWarp tr(u0, u1, u2, u3, v0, v1, v2, v3, x0, x1, x2, x3, y0, y1, y2, y3);
       
        /* warping point (u0,v0) in source quadrilateral
         * to point(x,y) in destination quadrilateral
         */
        int x,y;
        tr.warp(u0, v0, &x, &y);

ประสิทธิภาพการ Warp ใกล้เคียงกับเวอร์ชัน Matlab แต่ทำงานได้ไวกว่ามาก
Capture 

ใครสนใจดาวน์โหลดไปทดสอบกันได้ครับ

อัพบล็อกง่ายๆด้วย Windows Live Writer Beta

อัพบล็อกง่ายๆด้วย Windows Live Writer Beta
ดาวน์โหลด โปรแกรม
ทดสอบใส่รูป

ทดสอบใส่ video จาก youtube

ทดสอบใส่ตาราง

     
     
     

 

นอกจากนี้สามารถเขียนบลฺ็อกครั้งเดียว และอัพไปหลายๆที่ได้เลย เพราะผมเขียนบล็อกอยู่ 2 ที่

มี ภาพ Preview ให้ดูด้วย

image

ใครโปรเรื่อง HTML ยังแก้ไขได้โดยตรงด้วย

image

ลองเอาไปใช้กันดูนะครับ

ทดสอบการสร้างโปรเจคที่ใช้งาน wiiuse, OpenGL, OpenCV ร่วมกัน

ทดสอบการสร้างโปรเจคที่ใช้งาน wiiuse, OpenGL, OpenCV ร่วมกัน

ดาวน์โหลด

โค้ดที่ใช้ทดสอบ wiiuse

       /* Test wiimote
         */
        wiimote** wiimotes;
        int found, connected;

        /*
         *    Initialize an array of wiimote objects.
         *
         *    The parameter is the number of wiimotes I want to create.
         */
        wiimotes =  wiiuse_init(MAX_WIIMOTES);
        found = wiiuse_find(wiimotes, MAX_WIIMOTES, 5);
        if (!found) {
            printf ("No wiimotes found.");
            return 0;
        }
        wiiuse_rumble(wiimotes[0], 0);
        /*
         *    Disconnect the wiimotes
         */
        wiiuse_cleanup(wiimotes, MAX_WIIMOTES);

โค้ดที่ใช้ทดสอบ OpenCV

       /* test OpenCV
         */
        IplImage *img = cvLoadImage(".\\image.jpg");
        cv::namedWindow("Image:",1);
       
        IplImage *dst = cvCreateImage(cvGetSize(img),IPL_DEPTH_16S,3);
        IplImage *dst2 = cvCreateImage(cvGetSize(img),IPL_DEPTH_16S,3);
        cvLaplace(img, dst, 3);
        //cvLaplace(dst, dst2, 3);
        cv::imshow("Image:", dst);
        cvWaitKey();
        cvDestroyWindow("Image:");
        cvReleaseImage(&img);

 


โค้ดที่ใช้ทดสอบ OpenGL

       /* test OpenGL
         */
        char *targv[] = {""};
        glutInit (&argc, targv);
        glutInitDisplayMode (GLUT_DOUBLE | GLUT_DEPTH); //set the display to Double buffer, with depth
        glutGameModeString( "1024x768:32@30" ); //the settings for fullscreen mode
        glutEnterGameMode(); //set glut to fullscreen using the settings in the line above
        init (); //call the init function
        glutDisplayFunc (display); //use the display function to draw everything
        glutIdleFunc (display); //update any variables in display, display can be changed to anyhing, as long as you move the variables to be updated, in this case, angle++;
        glutReshapeFunc (reshape); //reshape the window accordingly

        glutKeyboardFunc (keyboard); //check the keyboard
        glutMainLoop (); //call the main loop}

20 สิงหาคม 2553

การคอมไพล์ไลบารี wiiuse ด้วย Visual Studio 2008

การคอมไพล์ไลบารี wiiuse ด้วย Visual Studio 2008
ผมนำเอาไลบารี wiiuse ที่คอมไฟล์มาแล้ว แต่ดันใช้ไม่ได้
จึงต้องคอมไพล์มันใหม่ แต่มีขั้นตอนยุ่งยากเหมือนกันเลยจะเอาวิธีที่ใช้แล้ว Work มาบรรยายให้ฟัง
ผมใช้ wiiuse ผ่าน ไลบารี ของ FWiine หรืออยากโหลดอันที่ผมใช้ไปเลยก็ได้
ได้มาจากป้อฝาแฝดผมเอง โหลดได้ที่นี่ 
และต้องใช้ Windows Driver Kit: WDK เป็นไลบารีที่ wiiuse เรียกใช้ตัว Bluetooth อีกที

1. Config Visual Studio

ไปที่ Tools > Options… > Projects and Solutions > VC++ Directories

เปลี่ยน Show directories for : Library files
เพิ่ม Directory ของ WDK ตัวอย่าง C:\WinDDK\7600.16385.1\lib\win7\i386
คลิก OK
image

2. ปรับ wiiuse project property
คลิกขวาที่ project wiiuse เลือก property
ไปที่ Confuguration Properties > C/C++ > General
ที่ Additional Include Directorties คลิก …
image
เพิ่ม Path ของ VC Standard Include ตัวอย่าง C:\Program Files\Microsoft Visual Studio 9.0\VC\include
และ Path ของ WDK API ตัวอย่าง C:\WinDDK\7600.16385.1\inc\api 
คลิก OK
image

ไปที่ Confuguration Properties > Linker > Input
ที่ Additional Include Directorties คลิก …
image

เพิ่ม Link ไฟล์ odbc32.lib odbccp32.lib Ws2_32.lib hid.lib setupapi.lib
image

3. ปรับ wiiuseexample property
คลิกขวาที่ wiiuserexample เลือก Property
ไปที่ Confuguration Properties > C/C++ > General ใส่ ..\..\src
image

ไปที่ Confuguration Properties > Linker > Input
ที่ Additional Dependencies ใส่ wiiuse.lib  คลิก OK

image

แค่นี้เป็นอันเสร็จคอมไพล์ได้แน่นอน งานนี้ขอขอบคุณ ป้อฝาแฝดที่ช่วยทำและให้คำแนะนำ

11 สิงหาคม 2553

การใช้งาน Wiimote ควบคุม Lego NXT

การใช้งาน Wiimote ควบคุม Lego NXT

แนะนำการใช้งาน Wiimote เป็นรีโมทของเครื่องเล่นเกม wii

และชุดฝึกทักษะหุ่นยนต์ LegoNXT ร่วมกัน
สิ่งที่ต้องเตรียม
1. wiimote
2. คอมพิวเตอร์ที่มีบลูทูธ 2.0+EDR
3. Lego NXT

โปรแกรม
1. Visual Studio C# 2008 ถ้าไม่มีแนะนำ Version ฟรี
2. Managed Library for Nintendo's Wiimote สำหรับติดต่อกับ wiimote
3. LogoAForge.NET Framework สำหรับติดต่อกับ Lego NXT ติดตั้งให้เรียบร้อย

เริ่มกันเลย
เปิดโปรเจ็ค ที่อยู่ใน samples\WiimoteTestCS ของ WiimoteLib เพื่อเปิด VS
เพิ่ม library

ให้เพิ่ม Reference ของ AForge.Robotics.Lego จะของในที่ๆติดตั้ง AForge \AForge.NET\Framework\Release


เปิด code ของ Form1.cs


ในส่วนของ Header ด้านบนเพิ่ม
using AForge.Robotics.Lego;


ในส่วนของ Constructor เพิ่ม
// NXT brick
        private NXTBrick nxt = new NXTBrick();
        private NXTBrick.MotorRunState[] runStates = new NXTBrick.MotorRunState[]
        {
            NXTBrick.MotorRunState.Idle,
            NXTBrick.MotorRunState.RampUp,
            NXTBrick.MotorRunState.Running,
            NXTBrick.MotorRunState.RampDown
        };

        // NXT brick
        private NXTBrick nxt = new NXTBrick();
        private NXTBrick.MotorRunState[] runStates = new NXTBrick.MotorRunState[]
        {
            NXTBrick.MotorRunState.Idle,
            NXTBrick.MotorRunState.RampUp,
            NXTBrick.MotorRunState.Running,
            NXTBrick.MotorRunState.RampDown
        };
เพิ่ม object ของ Lego NXT


        // walk
        bool walkOn = true;
        bool legLeft = true;
        System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();


        public void Walk(object sender, EventArgs eArgs)

        {
            NXTBrick.MotorState motorStateGo = new NXTBrick.MotorState();
            motorStateGo.Power = (sbyte)127;
            motorStateGo.TurnRatio = (sbyte)50;
            motorStateGo.Mode = NXTBrick.MotorMode.On;// NXTBrick.MotorMode.Brake, NXTBrick.MotorMode.None, NXTBrick.MotorMode.Regulated
            motorStateGo.RunState = runStates[2]; //0:Idle, 1:RampUp, 2:Running, 3:RampDown
            legLeft = !legLeft;
            if (legLeft)
            {
                //left leg forward
                // set motor's state
                if (nxt.SetMotorState(NXTBrick.Motor.C, motorStateGo) != true)
                {
                    System.Diagnostics.Debug.WriteLine("Failed setting motor state");
                }          
            }
            else
            {
                //Right leg forward
                if (nxt.SetMotorState(NXTBrick.Motor.B, motorStateGo) != true)
                {
                    System.Diagnostics.Debug.WriteLine("Failed setting motor state");
                }    
            }
        }


เพิ่ม Method สำหรับการเดิน

Link เมื่อกดปุ่ม Wiimote แล้วสั่งให้มอเตอร์ทำงาน หุ่นยนต์ก็จะเดิน
ภายใน Method UpdateWiimoteState จะมีตัวแปร ws ของ wiimote อยู่

ซึ่งเราจะใช้คำสั่ง if เช็คว่ามีการกดปุ่มนั้นๆหรือไม่ ถ้ามีเราจะสั่งให้หุ่นยนต์ เคลื่อนที่
โค๊ดตัวอย่างการกดปุ่มขึ้น
            if (ws.ButtonState.Up)
            {
                // your code when Press Up Buttom
            }

 เพียงเท่านั้นเราก็เชื่อมต่อ Wiimote กับ Lego NXT ได้แล้ว
อ่อ มันต้องเชื่อมต่อกันผ่านคอมนะครับ เชื่อมกันโดยตรงไม่ได้

ดาวน์โหลดซอร์สโค๊ด ไปศึกษาดูนะครับ
ติดอะไรก็เมลมาถามได้