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

Finch
classdef Finch < handle
    % Finch 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=Finch();  % Connects to Finch so make sure your hardware is
    %   connected
    %
    %   x=Finch('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 (Hidden=true)
        finchObj = []; % Object for underline communication to Finch Robot
        hLightSensor = []; % Graphics handle to Light Sensor graph
        hAccelerometer = [];% Graphics handle to Accelerometer graph
        hTemperature = [];% Graphics handle to Temperature graph
    end
    
    properties (SetAccess = private, GetAccess = public, Dependent = true)
        obstacleSensors
        temperature
        accelerations
        lightSensors
    end
    
    %% Methods
    methods
        function obj = Finch(varargin)
            %Finch Constructor
            
            % check nargin for simulation mode or not
            if nargin==0
                % Connect to hardware
                obj.finchObj = finchComm();
            else
                % Run in simulation mode
                obj.finchObj = finchComm(varargin);
            end
        end
        function delete(obj)
            % distructor, closes connection and deletes object
            delete(obj.finchObj);
            obj.finchObj = [];
        end
        function disp(obj) % display
            % disp, displays the object
            if ~isvalid(obj)
                disp('Connection close')
            else
                obj.finchObj.disp();
                Finch.getMethods();
                
            end
        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(freq,{'numeric'},{'real','finite','scalar','nonnegative'},'buzz','duration',2);
            
            obj.finchObj.buzz(freq,duration);
        end
        function sleep(obj,val) %#ok
            % 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);
            pause(val/1000); % They should pass value in milliseconds
        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 playClip(obj,str) %#ok
            % playClip(String fileLocation)
            % Plays a wav file over computer speakers at the specificied fileLocation path.
            
            validateattributes(str,{'string'},{},'playClip','Wave file name',1);
            if ~exist(str,'file')
                error('Please pass in a valid wave file');
            end
            [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) %#ok
            % 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 saySomething(obj,str,rep)
            % Not Implemented yet
            
            % 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.
            obj.finchObj.stop();
        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);
            
            %setWheelVelocities(leftWheel,rightWheel,[lengthTime in msec])
            if exist('duration','var')
                validateattributes(duration,{'numeric'},{'real','finite','scalar','nonnegative'},'setWheelVelocities','timeToHold',3);
                obj.finchObj.motor(leftWheel,rightWheel,duration);
            else
                obj.finchObj.motor(leftWheel,rightWheel);
            end
        end
        
        %% GET VALUE
        function valArray=get.obstacleSensors(obj)
            % valArray = getObstacleSensors()
            % Returns the value of both obstacle sensors.
            valArray = obj.finchObj.obstacleSensors();
        end
        function val = get.temperature(obj)
            % val = getTemperature()
            % The current temperature reading at the temperature probe.
            val = obj.finchObj.temperature();
        end
        function valArray = get.accelerations(obj)
            % val = getAccelerations()
            % Use this method to simultaneously return the current X, Y, and Z accelerations experienced by the robot.
            valArray = obj.finchObj.accelerometer();
        end
        function valArray = get.lightSensors(obj)
            % getLightSensors()
            % Returns a 2 integer array containing the current values of both light sensors.
            valArray = obj.finchObj.lightSensors();
        end
        
        %% SET
        function setLED(obj, ledColor, duration)
            %SETLED(RGB Color Value Triplet)
            %
            % setLED([red, green, blue])
            % Sets the color of the LED in the Finch's beak
            %
            validateattributes(ledColor,{'numeric'},{'2d','nonnegative','<=',255},'setLED');
            if exist('duration','var')
                validateattributes(duration,{'numeric'},{'scalar','nonnegative','<=',255},'setLED');
                obj.finchObj.led(ledColor(1),ledColor(2),ledColor(3),duration);
            else
                obj.finchObj.led(ledColor(1),ledColor(2),ledColor(3));
            end
        end
        
        %% IS functions
        function val = isFinchUpsideDown(obj)
            % isFinchUpsideDown()
            % This method returns true if the Finch is upside down, false otherwise
            accVal = obj.accelerations;
            % Check to see if z acceleration is negative or not
            if accVal(3)>0
                val = true;
            else
                val = false;
            end
        end
        function val = isLeftWingDown(obj)
            % isLeftWingDown()
            % This method returns true if the Finch's left wing is pointed
            % at the ground
            accVal = obj.accelerations;
            % Check to see if z acceleration is negative or not
            if accVal(3)<0 && accVal(2)>0
                val = true;
            else
                val = false;
            end
        end
        function val = isRightWingDown(obj)
            % isRightWingDown()
            % This method returns true if the Finch's right wing is pointed at the ground
            accVal = obj.accelerations;
            % Check to see if z acceleration is negative or not
            if accVal(3)<0 && accVal(2)<0
                val = true;
            else
                val = false;
            end
        end
        function val = isFinchLevel(obj)
            % isFinchLevel()
            % This method returns true if the Finch is on a flat surface
            accVal = obj.accelerations;
            % Check to see if x,y acceleration are close to zero all Acc is
            % down
            if accVal(1)<5 && accVal(2)<5
                val = true;
            else
                val = false;
            end
        end
        function val = isBeakDown(obj)
            % val = isBeakDown()
            % This method returns true if the beak is pointed at the floor,
            % false otherwise
            accVal = obj.accelerations;
            % Check to see if x acceleration is negative
            if accVal(1)<0
                val = true;
            else
                val = false;
            end
        end
        function val = isBeakUp(obj)
            % val = isBeakUp()
            % This method returns true if the beak is up (Finch sitting on its tail), false otherwise
            accVal = obj.accelerations;
            % Check to see if x acceleration is positive
            if accVal(1)>0
                val = true;
            else
                val = false;
            end
        end
        function val = isShaken(obj)
            % Not Implimented yet
            
            % val = isShaken()
            % Returns true if the Finch has been shaken since the last accelerometer read
            
            accVal = obj.accelerations;
            % Check to see if x acceleration is negative
            if accVal(3)>0
                val = true;
            else
                val = false;
            end
        end
        function val = isTapped(obj)
            % Not Implimented Yet
            
            % val = isTapped()
            % Returns true if the Finch has been tapped since the last accelerometer read
            accVal = obj.accelerations;
            % Check to see if x acceleration is negative
            if accVal(3)>0
                val = true;
            else
                val = false;
            end
        end
        
        function val = isTemperature(obj,val)
            % isTemperature(limit)
            % Returns true if the temperature is greater than the value specified by limit, false otherwise.
            tempVal = obj.temperature;
            if tempVal<val
                val = true;
            else
                val = false;
            end
        end
        function val = isLeftLightSensor(obj,sensorVal)
            % isLeftLightSensor(limit)
            % Returns true if the left light sensor is great than the value specified by limit, false otherwise.
            lightVal = obj.lightSensors;
            if lightVal(2)<sensorVal
                val = true;
            else
                val = false;
            end
        end
        function val = isRightLightSensor(obj,sensorVal)
            % val = isRightLightSensor(limit)
            % Returns true if the right light sensor is greater than the value specified by limit, false otherwise.
            lightVal = obj.lightSensors;
            if lightVal(1)<sensorVal
                val = true;
            else
                val = false;
            end
        end
        function val = isObstacle(obj)
            % val = isObstacle()
            % Returns true if either left or right obstacle sensor detect an obstacle.
            obstVal = obj.obstacleSensors;
            val = obstVal(1)||obstVal(2);
        end
        function val = isObstacleLeftSide(obj)
            % isObstacleLeftSide()
            % Returns true if there is an obstruction in front of the left side of the robot.
            obstVal = obj.obstacleSensors;
            val = obstVal(1);
        end
        function val = isObstacleRightSide(obj)
            % isObstacleRightSide()
            % Returns true if there is an obstruction in front of the right side of the robot.
            obstVal = obj.obstacleSensors;
            val = obstVal(2);
        end
        
        %% GRAPHICS
        function showLightSensorGraph(obj)
            % showLightSensorGraph()
            % Displays a graph of the left and right light sensor values.
            val=obj.lightSensors;
            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);
            title(['Light Sensor Graph:',obj.finchObj.disp]);
            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.
            
            % Just in case people send the return value from property which
            % has both values in a single variable do the right thing.
            if nargin==2
                b = a(2);
            end
            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.temperature;
            obj.hTemperature=plot(1,t);
            xlabel(get(obj.hTemperature,'parent'),'Reading');
            ylabel(get(obj.hTemperature,'parent'),'Temperature');
            set(obj.hTemperature,'LineWidth',2);
            title(['Temperature Sensor Graph:',obj.finchObj.disp]);
            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.accelerations;
            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);
            title(['Accelerometer Sensor Graph:',obj.finchObj.disp]);
            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)
        % Methods available to users without create object
        %
        function getMethods()
            % Finch.getMethods()
            %   Prints a nicely formatted list of Finch Robot's methods with links
            %   to their relevant help dialogs.
            fprintf('\nMethods for Finch Robot\n');
            fprintf('    <a href="matlab:help Finch.Finch">Finch()</a>\n');
            fprintf('    <a href="matlab:help Finch.delete">delete()</a>\n');
            fprintf('    <a href="matlab:help Finch.quit">quit()</a>\n');
            fprintf('\nUtilities\n');
            fprintf('    <a href="matlab:help Finch.buzz">buzz(frequency,timeDuration)</a>\n');
            fprintf('    <a href="matlab:help Finch.playClip">playClip(wavFile)</a>\n');
            fprintf('    <a href="matlab:help Finch.playTone">playTone(frequency,timeDuration)</a>\n');
            fprintf('    <a href="matlab:help Finch.sleep">sleep(timeDuration)</a>\n');
            %            fprintf('    <a href="matlab:help Finch.saySomething">saySomething(text)</a>\n');
            fprintf('\nMotor Control\n');
            fprintf('    <a href="matlab:help Finch.stopWheels">stopWheels()</a>\n');
            fprintf('    <a href="matlab:help Finch.setWheelVelocities">setWheelVelocities(LeftVelocity,RightVelocity,timeDuration)</a>\n');
            fprintf('\nSet LED\n');
            fprintf('    <a href="matlab:help Finch.setLED">setLED(obj, [red,green,blue],duration)</a>\n');
            fprintf('\nGet Sensor Data\n');
            fprintf('    <a href="matlab:help Finch.obstacleSensors">varArray(R,L)=obstacleSensors()</a>\n');
            fprintf('    <a href="matlab:help Finch.temperature">temp = temperature()</a>\n');
            fprintf('    <a href="matlab:help Finch.accelerations">varArray(x,y,z) = accelerations()</a>\n');
            fprintf('    <a href="matlab:help Finch.lightSensors">varArray(R,L) = lightSensors()</a>\n');
            fprintf('\nBoolean Tests\n');
            fprintf('    <a href="matlab:help Finch.isFinchUpsideDown">boolean = isFinchUpsideDown()</a>\n');
            fprintf('    <a href="matlab:help Finch.isLeftWingDown">boolean = isLeftWingDown()</a>\n');
            fprintf('    <a href="matlab:help Finch.isRightWingDown">boolean = isRightWingDown()</a>\n');
            fprintf('    <a href="matlab:help Finch.isFinchLevel">boolean = isFinchLevel()</a>\n');
            fprintf('    <a href="matlab:help Finch.isTemperature">boolean = isTemperature(testVal)</a>\n');
            fprintf('    <a href="matlab:help Finch.isLeftLightSensor">boolean = isLeftLightSensor(testVal)</a>\n');
            fprintf('    <a href="matlab:help Finch.isRightLightSensor">boolean = isRightLightSensor(testVal)</a>\n');
            fprintf('    <a href="matlab:help Finch.isObstacle">boolean = isObstacle()</a>\n');
            fprintf('    <a href="matlab:help Finch.isObstacleLeftSide">boolean = isObstacleLeftSide()</a>\n');
            fprintf('    <a href="matlab:help Finch.isObstacleRightSide">boolean = isObstacleRightSide()</a>\n');
            fprintf('    <a href="matlab:help Finch.isBeakDown">boolean = isBeakDown()</a>\n');
            fprintf('    <a href="matlab:help Finch.isBeakUp">boolean = isBeakUp()</a>\n');
            %            fprintf('    <a href="matlab:help Finch.isShaken">boolean = isShaken()</a>\n');
            %            fprintf('    <a href="matlab:help Finch.isTapped">boolean = isTapped()</a>\n');
            fprintf('\nGraphics\n');
            fprintf('    <a href="matlab:help Finch.showLightSensorGraph">showLightSensorGraph()</a>\n');
            fprintf('    <a href="matlab:help Finch.updateLightSensorGraph">updateLightSensorGraph()</a>\n');
            fprintf('    <a href="matlab:help Finch.closeLightSensorGraph">closeLightSensorGraph()</a>\n');
            fprintf('    <a href="matlab:help Finch.showTemperatureGraph">showTemperatureGraph()</a>\n');
            fprintf('    <a href="matlab:help Finch.updateTemperatureGraph">updateTemperatureGraph()</a>\n');
            fprintf('    <a href="matlab:help Finch.closeTemperatureGraph">closeTemperatureGraph()</a>\n');
            fprintf('    <a href="matlab:help Finch.showAccelerometerGraph">showAccelerometerGraph()</a>\n');
            fprintf('    <a href="matlab:help Finch.updateAccelerometerGraph">updateAccelerometerGraph()</a>\n');
            fprintf('    <a href="matlab:help Finch.closeAccelerometerGraph">closeAccelerometerGraph()</a>\n');
            fprintf('\n');
        end
        function setup()
            % Walk users through getting and installing connectivity code
            finchComm.setup();
        end
    end
    
    
end

Contact us