Educational materials

View   r2  >  r1  ...
ExWiiLabSpinningDiskDemo 2 - 31 Jul 2008 - Main.JordanBrindza
Line: 1 to 1
 
META TOPICPARENT name="WiiLabMATLABDemos"

WiiLab Example Code - Spinning Disk

Line: 173 to 173
 

Calculate the Disk Speed and Direction

Changed:
<
<
As stated before, the speed and direction the Disk spins in is based off of the Wiimote's Acceleration when the user releases the disk. There are two things that influence the speed, The Wiimotes Acceleration and where the cursor is positioned on the disk at the time it is released.

  • if the paddle will end up inside the bounds * then move the paddle as normal
  • if the paddle will end up above the upper bound * then move the paddle the rest of the distance to the boundary and no further
  • if the paddle will end up below the lower bound * then move the paddle the rest of the distance to the boundary and no further
>
>
As stated before, the speed and direction the Disk spins in is based off of the Wiimote's Acceleration when the user releases the disk. There are two things that influence the speed, The Wiimotes Acceleration and where the cursor is positioned on the disk at the time it is released. The following code determines the location of the cursor and the direction of the acceleration vector created by the X and Y velocities of the Wiimote. By calculating the total acceleration along the tangent of the disk we can approximate a relative speed for the disk.
 
% Calculate position and acceleration angles (0 >< 90)
Line: 246 to 239
  -- JordanBrindza - 31 Jul 2008
Changed:
<
<
>
>
 
META FILEATTACHMENT attachment="spinning_disk.bmp" attr="h" comment="" date="1217523289" name="spinning_disk.bmp" path="C:\Documents and Settings\brindza\My Documents\REU_SVN\trunk\Documentation\Pictures\MATLAB Demos\spinning_disk.bmp" size="1150294" stream="C:\Documents and Settings\brindza\My Documents\REU_SVN\trunk\Documentation\Pictures\MATLAB Demos\spinning_disk.bmp" tmpFilename="/usr/tmp/CGItemp39508" user="JordanBrindza" version="1"
META FILEATTACHMENT attachment="SpinningDisk.m" attr="" comment="" date="1217523312" name="SpinningDisk.m" path="C:\Documents and Settings\brindza\My Documents\REU_SVN\trunk\Matlab\SpinningDisk.m" size="7125" stream="C:\Documents and Settings\brindza\My Documents\REU_SVN\trunk\Matlab\SpinningDisk.m" tmpFilename="/usr/tmp/CGItemp39263" user="JordanBrindza" version="1"

ExWiiLabSpinningDiskDemo 1 - 31 Jul 2008 - Main.JordanBrindza
Line: 1 to 1
Added:
>
>
META TOPICPARENT name="WiiLabMATLABDemos"

WiiLab Example Code - Spinning Disk

Note: MATLAB R2007a or greater is required for this code to run correctly. The program uses the Wiimote class, along with the UND function set EG111-H.

Annotations

This program simulates a spinning disk. The program uses the Wiimotes acceleration to determine the speed and direction of the disk.



One thing to note is that the most complicated part of this demo's code is not associated with the Wiimote interaction but in determining the direction and speed of the disk.

Program Breakdown

The program is fairly large so I have broken it down into its vital blocks to describe each in detail. The complete file is attached at the bottom of the page.

Initialization

The program starts by connecting to the Wiimote. This is a very simple task using the global functions.

% Create an instance of the wiimote and connect
initializeWiimote()

After the Wiimote is connected we are going to initialize the game window. This involves the following:

  • Creating the local variables for the program
  • Creating the main window
  • Creating the labels to display the acceleration values
  • Drawing the disk

% Constants
diskRadius = 100;     % # indicating the radius of the disk
diskCenter = [150 150];
cursorRadius = 2;     % # indicating the radius of the cursor
frictionCoef = .02;
wedges = 8;
wedgeColors =  ['b' 'g' 'r' 'y' 'b' 'g' 'r' 'y'];

% Variables
posTheta = 0;
posQuad = 0;
velTheta = 0;
velQuad = 0;


% Initialize Window
% -----------------------------------------------------------------
% Init basic window
initializeWindow(0);
    
%initialize text display
x_accelDispLbl = writeText(20,280,'X accel = ');
y_accelDispLbl = writeText(20,270,'Y accel = ');
diskVelDispLbl = writeText(20,260,'Disk vel = ');
x_accelDisp = writeText(50, 280, 'xx');
y_accelDisp = writeText(50, 270, 'xx');
diskVelDisp = writeText(50, 260, 'xx');
    
    
% Init the wiimote cursor
wiimoteCursor = drawCircle(150, 150, cursorRadius, 'black');
  
% Init the main disk    
disk = drawCircleWedges(diskCenter(1), diskCenter(2), diskRadius, wedges, wedgeColors);
 
  
% Local Variables
onDisk = false;
prevAttached = false;
attached = false;
diskVel = 0;
% -----------------------------------------------------------------

Main Loop

For the Spinning Disk program, our main loop will execute until "HOME" is pressed on the Wiimote.

Inside the loop the following things are done:

  1. Move the user cursor based on the Wiimote's Acceleration.
  2. If the Wiimote is on the Disk and the User is pressing "B", then record the Acceleration values to spin the disk when the User releases the disk.
  3. Calculating the disks direction and speed based on the recorded acceleration (detailed in the next section)
  4. Redraw and Pause. This is one of the most important pieces of any program like this. You need to make sure that you have a pause(xx) at the end of every loop that uses the Wiimote or EG111-H functions. MATLAB will not execute any callback functions until it reaches a pause(xx). If the pause is omitted you will begin to experience unusual behavior from the Wiimote class.

% While "Home" is not pressed
while (~isButtonPressed('HOME'))

    %  Determine if the wiimoteCursor is on the disk
    % ---------------------------------------------
    [xc yc] = getCenter(wiimoteCursor);
            
    distanceFromDiskCenter = sqrt((xc-diskCenter(1))^2 + (yc-diskCenter(2))^2);
            
    if(distanceFromDiskCenter <= diskRadius)
        onDisk = true;
    else
        onDisk = false;
    end             
    % ---------------------------------------------
            
                        
    if(isButtonPressed('B'))
                               
        % if the cursor is on the disk
        if(onDisk)
            attached = true;                                        
        else
            attached = false;                    
        end                
    else
         if(attached)
             attached = false;
             prevAttached = true;
         else
              prevAttached = false;
         end
    end
            
    if(prevAttached)

        [x_accel y_accel] = getWiimoteAccel();
                        
        % Calculate Disk Velocity
        % -----------------------------------------------------
                            

        set(x_accelDisp, 'String', x_accel);
        set(y_accelDisp, 'String', y_accel);
        set(diskVelDisp, 'String', diskVel);
               
        % Draw Vector
        try
            hide(vector);
            hide(arrow);
        catch me
        end
        
        vector = drawLine(xc, yc, xc+(2*x_accel), yc+(2*y_accel), 'k');
        %------------------------------------------------------
                                        
    end                
                        
    % If the Wiimote is "attached" to the disk
    % don't move the wiimote
    if(~attached)
        rotate(disk, [0 0 1], diskVel);
               
        % If the disk is rotating decrease its speed according to
        % the "frictionCoef"
        if(diskVel ~= 0)
            diskVel = diskVel - diskVel * frictionCoef;
        end
                
        % Update the wiimote cursor position
        moveObjectWithWiimote(wiimoteCursor, 1, false);
    end
           
    redraw();
    pause(.01);
            
end % while

Calculate the Disk Speed and Direction

As stated before, the speed and direction the Disk spins in is based off of the Wiimote's Acceleration when the user releases the disk. There are two things that influence the speed, The Wiimotes Acceleration and where the cursor is positioned on the disk at the time it is released.

  • if the paddle will end up inside the bounds * then move the paddle as normal
  • if the paddle will end up above the upper bound * then move the paddle the rest of the distance to the boundary and no further
  • if the paddle will end up below the lower bound * then move the paddle the rest of the distance to the boundary and no further

% Calculate position and acceleration angles (0 >< 90)
posTheta = atan(abs(yc-diskCenter(2))/abs(xc-diskCenter(1))) * (180/pi);
velTheta = atan(abs(y_accel)/abs(x_accel)) * (180/pi);

% Calc quadrent
if((xc - diskCenter(1) > 0) && (yc - diskCenter(2) > 0))
    posQuad = 1;
elseif ((xc - diskCenter(1) > 0) && (yc - diskCenter(2) < 0))
    posQuad = 4;    
elseif ((xc - diskCenter(1) < 0) && (yc - diskCenter(2) < 0))
    posQuad = 3;
elseif ((xc - diskCenter(1) < 0) && (yc - diskCenter(2) > 0))
    posQuad = 2;
end

if (x_accel > 0 && y_accel > 0)
    velQuad = 1;
elseif (x_accel > 0 && y_accel < 0)
    velQuad = 4;
elseif (x_accel < 0 && y_accel < 0)
    velQuad = 3;
elseif (x_accel < 0 && y_accel > 0)
    velQuad = 2;
end

switch (velQuad)
    case 2
        velTheta = 180 - velTheta;                        
    case 3
        velTheta = 180 + velTheta;
    case 4
        velTheta = 360 - velTheta;
    end

switch (posQuad)
    case 1
        theta = (90 - posTheta) + velTheta;
    case 2
        theta = -1*(90 - posTheta) + velTheta;
    case 3
        theta = (90 - posTheta) + velTheta;
    case 4
        theta = -1*(90 - posTheta) + velTheta;
end

diskVel = cos((theta*pi/180)) * sqrt(x_accel^2 + y_accel^2);                    
% factor in distance from the center
diskVel = 2 * diskVel * (distanceFromDiskCenter/diskRadius);     
if(posQuad < 3)
    diskVel = -1*diskVel;
end
%--------------------------------------------------------------

Raw Source Code

The source code is available as a .m file download at the bottom of the page.

-- JordanBrindza - 31 Jul 2008

META FILEATTACHMENT attachment="spinning_disk.bmp" attr="h" comment="" date="1217523289" name="spinning_disk.bmp" path="C:\Documents and Settings\brindza\My Documents\REU_SVN\trunk\Documentation\Pictures\MATLAB Demos\spinning_disk.bmp" size="1150294" stream="C:\Documents and Settings\brindza\My Documents\REU_SVN\trunk\Documentation\Pictures\MATLAB Demos\spinning_disk.bmp" tmpFilename="/usr/tmp/CGItemp39508" user="JordanBrindza" version="1"
META FILEATTACHMENT attachment="SpinningDisk.m" attr="" comment="" date="1217523312" name="SpinningDisk.m" path="C:\Documents and Settings\brindza\My Documents\REU_SVN\trunk\Matlab\SpinningDisk.m" size="7125" stream="C:\Documents and Settings\brindza\My Documents\REU_SVN\trunk\Matlab\SpinningDisk.m" tmpFilename="/usr/tmp/CGItemp39263" user="JordanBrindza" version="1"

Revision 2r2 - 31 Jul 2008 - 18:22:15 - JordanBrindza
Revision 1r1 - 31 Jul 2008 - 16:55:14 - JordanBrindza
This site is powered by the TWiki collaboration platformCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback
Syndicate this site RSSATOM