Code covered by the BSD License  

Highlights from
MATLAB Support Package for Finch Robot

image thumbnail

MATLAB Support Package for Finch Robot

by

 

20 Jan 2012 (Updated )

MATLAB connectivity code to a Finch Robot

mFinch
classdef mFinch < handle
    % mFinch MATLAB Class for your Finch Robot that is consistent with the
    % Java interface, but uses MATLAB plots for the graphics and has a simulation mode.
    %
    % Please visit http://www.finchrobot.com for more information about
    % the Finch Robot teaching platform.
    %
    % Usage:
    %   x=mFinch();  % Connects to Finch so make sure your hardware is
    %   connected
    %
    %   x=mFinch('test'); % Creates Finch object using simulation. This
    %   allows you to run your code even if you don't have a Finch
    %   connected.  Simulated sensor output returns random data.
    
    
    %   MATLAB Support Package for Finch Robot
    %   Version 1.0
    %   Copyright 2011 The MathWorks, Inc.
    
    %%
    % See getting started guide in pdf <./gettingStarted.pdf here>
    % or in html <./gettingStarted.html here>
    
    %% Properties
    properties (Access=private)
        javaObj = [];
    end
    
    properties (Hidden=true)
        chkp = true;   % Checks parameters before every operation
        hLightSensor = []; % Graphics handle to Light Sensor graph
        hAccelerometer = [];% Graphics handle to Accelerometer graph
        hTemperature = [];% Graphics handle to Temperature graph
    end
    
    %% Methods
    methods
        function obj = mFinch(varargin)
            %MFINCH Constructor
            
            % check nargin
            if nargin==0
                try
                    if isempty(regexp(javaclasspath,'finch.jar','once'))
                        javaaddpath finch.jar
                    end
                    %import edu.cmu.ri.createlab.terk.robot.finch.*
                    
                    obj.javaObj = edu.cmu.ri.createlab.terk.robot.finch.Finch();
                catch ME
                    error(['Was not able to find/load the finch.jar file.  ',...
                        'Please make sure this file is located with the mFinch.m file']);
                end
            else
                disp('Note: DEMO connection will be created');
                disp('Do not pass anything to constructor to connect with the hardware.');
                obj.javaObj = [];
                obj.chkp = false; % Used to flag Simulation mode
            end
        end
        function delete(obj)
            % distructor, closes connection and deletes object
            if obj.chkp
                obj.javaObj.quit();
            end
        end
        function disp(obj) % display
            % disp, displays the object
            if obj.chkp
                disp('Connected to your Finch');
            else
                disp('Currently using Simulation mode');
            end
            mFinch.getMethods();
        end
        
        %% UTILITIES
        function buzz(obj,freq,duration)
            % buzz(frequency, duration)
            % Plays a tone at the specified frequency for the specified
            % duration in milliseconds on the Finch's internal buzzer.
            
            % Error checking on passed parameters
            validateattributes(freq,{'numeric'},{'real','scalar','<',8192,'>',100},'buzz','frequency',1);
            validateattributes(duration,{'numeric'},{'real','finite','scalar','nonnegative'},'buzz','duration',2);
            
            if obj.chkp
                obj.javaObj.buzz(freq,duration);
            else
                % Simulate the buzz sound from Finch
                freqArray = sin(2*pi*(0:1/8192:duration/1000)*freq); %Expect duration to be in milliseconds
                sound(freqArray);
            end
        end
        function sleep(obj,val)
            % sleep(duration)
            % This method uses Thread.sleep to cause the currently running
            % program to sleep for the specified number of milliseconds.
            
            validateattributes(val,{'numeric'},{'real','finite','scalar','nonnegative'},'sleep','time',1);
            
            if obj.chkp
                obj.javaObj.sleep(val);
            else
                pause(val/1000); % They should pass value in milliseconds
            end
        end
        function playClip(obj,str)
            % playClip(String fileLocation)
            % Plays a wav file over computer speakers at the specificied fileLocation path.
            
            
            [y,fs,nbits]=wavread(str); %%TODO need to make sure the file exists and is a .wav file
            sound(y,fs,nbits);
        end
        function playTone(obj,frequency,duration,c)
            % playTone(frequency, duration)
            % Plays a tone over the computer speakers or headphones at a given frequency (in Hertz) for a specified duration in milliseconds
            %
            % playTone(int frequency, int volume, int duration)
            % Plays a tone over the computer speakers or headphones at a given frequency (in Hertz) for a specified duration in milliseconds at a specified volume
            
            validateattributes(frequency,{'numeric'},{'real','scalar','<',8192,'>',100},'playTone','frequency',1);
            
            if exist('c','var')
                validateattributes(c,{'numeric'},{'real','finite','scalar','nonnegative'},'playTone','duration',2);
                freqArray = sin(2*pi*(0:1/8192:c*1000)*frequency)*duration;
            else
                validateattributes(duration,{'numeric'},{'real','finite','scalar','nonnegative'},'playTone','duration',2);
                freqArray = sin(2*pi*(0:1/8192:duration*1000)*frequency);
            end
            sound(freqArray);
        end
        function quit(obj)
            % quit()
            % This method properly closes the connection with the Finch and
            % resets the Finch so that it is immediately ready to be
            % controlled by subsequent programs.  It also calls the
            % destrutor on the object
            delete(obj);
        end
        function saySomething(obj,str,rep)
            % saySomething(String sayThis)
            % Takes the text of 'sayThis' and synthesizes it into a sound file and plays the sound file over computer speakers.
            %
            % saySomething(String sayThis, int duration)
            % Takes the text of 'sayThis' and synthesizes it into a sound file and plays the sound file over computer speakers.
            
            %%TODO Check for valid input
            if obj.chkp
                if exist('rep','var')
                    obj.javaObj.saySomething(str,rep);
                else
                    obj.javaObj.saySomething(str);
                end
            else
                %%TODO Add speach on Windows using .NET interface to speach
            end
        end
        
        %% MOTOR CONTROL
        function stopWheels(obj)
            % stopWheels()
            % Stops both wheels.
            if obj.chkp
                obj.javaObj.stopWheels();
            end
        end
        function setWheelVelocities(obj,leftWheel,rightWheel,duration)
            % setWheelVelocities(int leftVelocity, int rightVelocity)
            % This method simultaneously sets the velocities of both wheels.
            %
            % setWheelVelocities(int leftVelocity, int rightVelocity, int timeToHold)
            % This method simultaneously sets the velocities of both wheels.
            
            validateattributes(leftWheel,{'numeric'},{'real','finite','scalar','<=',255,'>=',-255},'setWheelVelocities','LeftVelocity',1);
            validateattributes(rightWheel,{'numeric'},{'real','finite','scalar','<=',255,'>=',-255},'setWheelVelocities','RightVelocity',2);
            
            if obj.chkp
                %setWheelVelocities(leftWheel,rightWheel,[lengthTime in msec])
                if exist('duration','var')
                    validateattributes(duration,{'numeric'},{'real','finite','scalar','nonnegative'},'setWheelVelocities','timeToHold',3);
                    obj.javaObj.setWheelVelocities(leftWheel,rightWheel,duration);
                else
                    obj.javaObj.setWheelVelocities(leftWheel,rightWheel);
                end
            end
        end
        
        %% GET VALUE
        function [Rval,Lvar]=getObstacleSensors(obj)
            % [R,L] = getObstacleSensors()
            % Returns the value of both obstacle sensors.
            if obj.chkp
                valArray = obj.javaObj.getObstacleSensors();
                Rval = double(valArray(1));
                Lval = double(valArray(2));
            else
                Rval = round(rand(1));
                Lval = round(rand(1));
            end
        end
        function val = getTemperature(obj)
            % getTemperature()
            % The current temperature reading at the temperature probe.
            if obj.chkp
                val = double(obj.javaObj.getTemperature());
            else
                val = rand(1)*100;
            end
        end
        function valArray = getAccelerations(obj)
            % val = getAccelerations()
            % Use this method to simultaneously return the current X, Y, and Z accelerations experienced by the robot.
            if obj.chkp
                valArray = double(obj.javaObj.getAccelerations());
            else
                valArray = rand(3,1);
            end
        end
        function val = getXAcceleration(obj)
            % val = getXAcceleration()
            % This method returns the current X-axis acceleration value experienced by the robot.
            if obj.chkp
                val = double(obj.javaObj.getXAcceleration());
            else
                val = rand(1);
            end
        end
        function val = getYAcceleration(obj)
            % val = getYAcceleration()
            % This method returns the current Y-axis acceleration value experienced by the robot.
            if obj.chkp
                val = double(obj.javaObj.getYAcceleration());
            else
                val = rand(1);
            end
        end
        function val = getZAcceleration(obj)
            % val = getZAcceleration()
            % This method returns the current Z-axis acceleration value experienced by the robot.
            if obj.chkp
                val = double(obj.javaObj.getZAcceleration());
            else
                val = rand(1);
            end
        end
        function valArray = getLightSensors(obj)
            % getLightSensors()
            % Returns a 2 integer array containing the current values of both light sensors.
            if obj.chkp
                valArray = double(obj.javaObj.getLightSensors());
            else
                valArray = rand(2,1);
            end
        end
        function val = getRightLightSensor(obj)
            % getRightLightSensor()
            % Returns the value of the right light sensor
            if obj.chkp
                val = double(obj.javaObj.getRightLightSensor());
            else
                val = rand(1);
            end
        end
        function val = getLeftLightSensor(obj)
            % getLeftLightSensor()
            % Returns the value of the left light sensor
            if obj.chkp
                val = double(obj.javaObj.getLeftLightSensor());
            else
                val = rand(1);
            end
        end
        
        %% SET
        function setLED(obj, red,green,blue,duration)
            %SETLED(RGB Color Value)
            %
            % setLED(int red, int green, int blue)
            % Sets the color of the LED in the Finch's beak
            %
            % setLED(int red, int green, int blue, int duration)
            % Sets the color of the LED in the Finch's beak for the length of time specified by duration.
            validateattributes(red,{'numeric'},{'scalar','nonnegative','<=',255},'setLED','red',1);
            validateattributes(green,{'numeric'},{'scalar','nonnegative','<=',255},'setLED','green',2);
            validateattributes(blue,{'numeric'},{'scalar','nonnegative','<=',255},'setLED','blue',3);
            
            
            if obj.chkp
                if exist('duration','var')
                    validateattributes(red,{'numeric'},{'real','finite','scalar','nonnegative'},'setLED','duration',3);
                    obj.javaObj.setLED(red,green,blue,duration);
                else
                    obj.javaObj.setLED(red,green,blue);
                end
            end
        end
        
        %% IS functions
        function val = isFinchUpsideDown(obj)
            % isFinchUpsideDown()
            % This method returns true if the Finch is upside down, false otherwise
            if obj.chkp
                val = boolean(obj.javaObj.isFinchUpsideDown());
            else
                val = round(rand(1));
            end
        end
        function val = isLeftWingDown(obj)
            % isLeftWingDown()
            % This method returns true if the Finch's left wing is pointed
            % at the ground
            if obj.chkp
                val = boolean(obj.javaObj.isLeftWingDown());
            else
                val = round(rand(1));
            end
        end
        function val = isRightWingDown(obj)
            % isRightWingDown()
            % This method returns true if the Finch's right wing is pointed at the ground
            if obj.chkp
                val = boolean(obj.javaObj.isRightWingDown());
            else
                val = round(rand(1));
            end
        end
        function val = isFinchLevel(obj)
            % isFinchLevel()
            % This method returns true if the Finch is on a flat surface
            if obj.chkp
                val = boolean(obj.javaObj.isFinchLevel());
            else
                val = boolean(round(rand(1)));
            end
        end
        function val = isTemperature(obj,val)
            % isTemperature(double limit)
            % Returns true if the temperature is greater than the value specified by limit, false otherwise.
            if obj.chkp
                val = boolean(obj.javaObj.isTemperature(val));
            else
                t = obj.getTemperature();
                val = (t>=val);
            end
        end
        function val = isLeftLightSensor(obj,sensorVal)
            % isLeftLightSensor(int limit)
            % Returns true if the left light sensor is great than the value specified by limit, false otherwise.
            if obj.chkp
                val = boolean(obj.javaObj.isLeftLightSensor(sensorVal));
            else
                val = boolean(round(rand(1)));
            end
        end
        function val = isRightLightSensor(obj,sensorVal)
            % val = isRightLightSensor(int limit)
            % Returns true if the right light sensor is greater than the value specified by limit, false otherwise.
            if obj.chkp
                val = boolean(obj.javaObj.isRightLightSensor(sensorVal));
            else
                val = boolean(round(rand(1)));
            end
        end
        function val = isObstacle(obj)
            % val = isObstacle()
            % Returns true if either left or right obstacle sensor detect an obstacle.
            if obj.chkp
                val = boolean(obj.javaObj.isObstacle());
            else
                val = boolean(round(rand(1)));
            end
        end
        function val = isObstacleLeftSide(obj)
            % isObstacleLeftSide()
            % Returns true if there is an obstruction in front of the left side of the robot.
            if obj.chkp
                val = boolean(obj.javaObj.isObstacleLeftSide());
            else
                val = boolean(round(rand(1)));
            end
        end
        function val = isObstacleRightSide(obj)
            % isObstacleRightSide()
            % Returns true if there is an obstruction in front of the right side of the robot.
            if obj.chkp
                val = boolean(obj.javaObj.isObstacleRightSide());
            else
                val = boolean(round(rand(1)));
            end
            
        end
        function val = isBeakDown(obj)
            % val = isBeakDown()
            % This method returns true if the beak is pointed at the floor,
            % false otherwise
            if obj.chkp
                val = boolean(obj.javaObj.isBreakDown());
            else
                val = boolean(round(rand(1)));
            end
        end
        function val = isBeakUp(obj)
            % val = isBeakUp()
            % This method returns true if the beak is up (Finch sitting on its tail), false otherwise
            if obj.chkp
                val = boolean(obj.javaObj.isBreakUp());
            else
                val = boolean(round(rand(1)));
            end
        end
        function val = isShaken(obj)
            % val = isShaken()
            % Returns true if the Finch has been shaken since the last accelerometer read
            if obj.chkp
                val = boolean(obj.javaObj.isShaken());
            else
                val = boolean(round(rand(1)));
            end
        end
        function val = isTapped(obj)
            % val = isTapped()
            % Returns true if the Finch has been tapped since the last accelerometer read
            if obj.chkp
                val = boolean(obj.javaObj.isTapped());
            else
                val = boolean(round(rand(1)));
            end
        end
        
        %% GRAPHICS
        function showLightSensorGraph(obj)
            % showLightSensorGraph()
            % Displays a graph of the left and right light sensor values.
            [val]=obj.getLightSensors();
            obj.hLightSensor=plot(1,[val(1);val(2)]);
            xlabel(get(obj.hLightSensor(1),'parent'),'Reading');
            ylabel(get(obj.hLightSensor(1),'parent'),'Value');
            set(obj.hLightSensor(1),'LineWidth',2);
            set(obj.hLightSensor(2),'LineWidth',2);
            drawnow;
        end
        function updateLightSensorGraph(obj,a,b)
            % updateLightSensorGraph(int leftSensor, int rightSensor)
            % Updates the light sensor graph with the left and right light sensor data.
            if ishandle(obj.hLightSensor(1))
                xData = get(obj.hLightSensor(1),'xdata');
                yData = get(obj.hLightSensor(1),'ydata');
                set(obj.hLightSensor(1),'XData',[xData,xData(end)+1],'YData',[yData,a]);
                yData = get(obj.hLightSensor(2),'ydata');
                set(obj.hLightSensor(2),'XData',[xData,xData(end)+1],'YData',[yData,b]);
                drawnow;
            else
                error('Plot closed');
            end
        end
        function closeLightSensorGraph(obj)
            % closeLightSensorGraph()
            % Closes the opened Light sensor Graph
            if ishandle(obj.hLightSensor(1))
                
                close(get(get(obj.hLightSensor(1),'parent'),'parent'));
            end
            obj.hLightSensor = [];
        end
        function showTemperatureGraph(obj)
            % showTemperatureGraph()
            % Displays a graph of the temperature value
            t=obj.getTemperature();
            obj.hTemperature=plot(1,t);
            xlabel(get(obj.hTemperature,'parent'),'Reading');
            ylabel(get(obj.hTemperature,'parent'),'Temperature');
            set(obj.hTemperature,'LineWidth',2);
            drawnow;
        end
        function updateTemperatureGraph(obj,val)
            % updateTemperatureGraph(double temp)
            % Updates the temperature graph with the most recent temperature data
            if ishandle(obj.hTemperature)
                xData = get(obj.hTemperature,'xdata');
                yData = get(obj.hTemperature,'ydata');
                set(obj.hTemperature,'XData',[xData,xData(end)+1],'YData',[yData,val]);
                drawnow;
            else
                error('Plot closed');
            end
        end
        function closeTemperatureGraph(obj)
            % closeTemperatureGraph()
            % Closes the opened temperature Graph
            if ishandle(obj.hTemperature)
                close(get(get(obj.hTemperature,'parent'),'parent'));
            end
            obj.hTemperature = [];
        end
        function showAccelerometerGraph(obj)
            % showAccelerometerGraph()
            % Displays a graph of the X, Y, and Z accelerometer values.
            val = obj.getAccelerations();
            obj.hAccelerometer=plot3([0,val(1)],[0,val(2)],[0,val(3)]);
            xlabel(get(obj.hAccelerometer,'parent'),'X - Accelerometer');
            ylabel(get(obj.hAccelerometer,'parent'),'Y - Accelerometer');
            zlabel(get(obj.hAccelerometer,'parent'),'Z - Accelerometer');
            set(obj.hAccelerometer,'LineWidth',2);
            drawnow;
        end
        function updateAccelerometerGraph(obj,a,b,c)
            % updateAccelerometerGraph(double xVal, double yVal, double zVal)
            % updates the accelerometer graph with accelerometer data specified by xVal, yVal, and zVal.
            if ishandle(obj.hAccelerometer)
            if nargin~=4
                set(obj.hAccelerometer,'XData',[0,a(1)],'YData',[0,a(2)],'ZData',[0,a(3)]);
            else
                set(obj.hAccelerometer,'XData',[0,a],'YData',[0,b],'ZData',[0,c]);
            end
            drawnow;
            else
                error('Plot closed');
            end
        end
        function closeAccelerometerGraph(obj)
            % closeAccelerometerGraph()
            % Closes the opened Accelerometer Graph
            if ishandle(obj.hAccelerometer)
                close(get(get(obj.hAccelerometer,'parent'),'parent'));
            end
            obj.hAccelerometer = [];
        end
        
    end
    %% static methods
    methods(Static)
        %% nicely formatted methods list with help links
        function getMethods()
            % mFinch.getMethods()
            %   Prints a nicely formatted list of Finch Robot's methods with links
            %   to their relevant help dialogs.
            fprintf('\nMethods for mFinch Robot\n');
            fprintf('    <a href="matlab:help mFinch.mFinch">mFinch()</a>\n');
            fprintf('    <a href="matlab:help mFinch.delete">delete()</a>\n');
            fprintf('    <a href="matlab:help mFinch.quit">quit()</a>\n');
            fprintf('\nUtilities\n');
            fprintf('    <a href="matlab:help mFinch.buzz">buzz(frequency,timeDuration)</a>\n');
            fprintf('    <a href="matlab:help mFinch.playClip">playClip(wavFile)</a>\n');
            fprintf('    <a href="matlab:help mFinch.playTone">playTone(frequency,timeDuration)</a>\n');
            fprintf('    <a href="matlab:help mFinch.sleep">sleep(timeDuration)</a>\n');
            fprintf('    <a href="matlab:help mFinch.saySomething">saySomething(text)</a>\n');
            fprintf('\nMotor Control\n');
            fprintf('    <a href="matlab:help mFinch.stopWheels">stopWheels()</a>\n');
            fprintf('    <a href="matlab:help mFinch.setWheelVelocities">setWheelVelocities(LeftVelocity,RightVelocity,timeDuration)</a>\n');
            fprintf('\nSet LED\n');
            fprintf('    <a href="matlab:help mFinch.setLED">setLED(obj, red,green,blue,duration)</a>\n');
            fprintf('\nGet Sensor Data\n');
            fprintf('    <a href="matlab:help mFinch.getObstacleSensors">[R,L]=getObstacleSensors()</a>\n');
            fprintf('    <a href="matlab:help mFinch.getTemperature">temp = getTemperature()</a>\n');
            fprintf('    <a href="matlab:help mFinch.getAccelerations">varArray = getAccelerations()</a>\n');
            fprintf('    <a href="matlab:help mFinch.getAccelerations">varArray = getAccelerations()</a>\n');
            fprintf('    <a href="matlab:help mFinch.getXAccelerations">var = getXAccelerations()</a>\n');
            fprintf('    <a href="matlab:help mFinch.getYAccelerations">var = getYAccelerations()</a>\n');
            fprintf('    <a href="matlab:help mFinch.getZAccelerations">var = getZAccelerations()</a>\n');
            fprintf('    <a href="matlab:help mFinch.getLightSensors">varArray = getLightSensors()</a>\n');
            fprintf('    <a href="matlab:help mFinch.getRightLightSensors">var = getRightLightSensors()</a>\n');
            fprintf('    <a href="matlab:help mFinch.getLeftLightSensors">var = getLeftLightSensors()</a>\n');
            fprintf('\nBoolean Tests\n');
            fprintf('    <a href="matlab:help mFinch.isFinchUpsideDown">boolean = isFinchUpsideDown()</a>\n');
            fprintf('    <a href="matlab:help mFinch.isLeftWingDown">boolean = isLeftWingDown()</a>\n');
            fprintf('    <a href="matlab:help mFinch.isRightWingDown">boolean = isRightWingDown()</a>\n');
            fprintf('    <a href="matlab:help mFinch.isFinchLevel">boolean = isFinchLevel()</a>\n');
            fprintf('    <a href="matlab:help mFinch.isTemperature">boolean = isTemperature(testVal)</a>\n');
            fprintf('    <a href="matlab:help mFinch.isLeftLightSensor">boolean = isLeftLightSensor(testVal)</a>\n');
            fprintf('    <a href="matlab:help mFinch.isRightLightSensor">boolean = isRightLightSensor(testVal)</a>\n');
            fprintf('    <a href="matlab:help mFinch.isObstacle">boolean = isObstacle()</a>\n');
            fprintf('    <a href="matlab:help mFinch.isObstacleLeftSide">boolean = isObstacleLeftSide()</a>\n');
            fprintf('    <a href="matlab:help mFinch.isObstacleRightSide">boolean = isObstacleRightSide()</a>\n');
            fprintf('    <a href="matlab:help mFinch.isBeakDown">boolean = isBeakDown()</a>\n');
            fprintf('    <a href="matlab:help mFinch.isBeakUp">boolean = isBeakUp()</a>\n');
            fprintf('    <a href="matlab:help mFinch.isShaken">boolean = isShaken()</a>\n');
            fprintf('    <a href="matlab:help mFinch.isTapped">boolean = isTapped()</a>\n');
            fprintf('\nGraphics\n');
            fprintf('    <a href="matlab:help mFinch.showLightSensorGraph">showLightSensorGraph()</a>\n');
            fprintf('    <a href="matlab:help mFinch.updateLightSensorGraph">updateLightSensorGraph()</a>\n');
            fprintf('    <a href="matlab:help mFinch.closeLightSensorGraph">closeLightSensorGraph()</a>\n');
            fprintf('    <a href="matlab:help mFinch.showTemperatureGraph">showTemperatureGraph()</a>\n');
            fprintf('    <a href="matlab:help mFinch.updateTemperatureGraph">updateTemperatureGraph()</a>\n');
            fprintf('    <a href="matlab:help mFinch.closeTemperatureGraph">closeTemperatureGraph()</a>\n');
            fprintf('    <a href="matlab:help mFinch.showAccelerometerGraph">showAccelerometerGraph()</a>\n');
            fprintf('    <a href="matlab:help mFinch.updateAccelerometerGraph">updateAccelerometerGraph()</a>\n');
            fprintf('    <a href="matlab:help mFinch.closeAccelerometerGraph">closeAccelerometerGraph()</a>\n');
            fprintf('\n');
        end
    end
    
    
end

Contact us