[ return ]

matlab.pl



#
#  file: matlab.pl
#
#  Matlab interface routines
#
#

#     Copyright (C) 1995 Andrew H. Fagg (af0a@robotics.usc.edu)
#     
#     This program is free software; you can redistribute it and/or
#     modify it under the terms of the GNU General Public License
#     as published by the Free Software Foundation; either version 2
#     of the License, or any later version.
#     
#     This program is distributed in the hope that it will be useful,
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#     GNU General Public License for more details.
#     
#     You should have received a copy of the GNU General Public License
#     along with this program; if not, write to the Free Software
#     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#

#
#  sub write_desired
#
#  Write out the desired vector in matlab format
#

sub write_desired
{
    local($fname, @rest) = @_;

    local(@goal) = @rest[0..($#rest-1)/2];
    local(@level) = @rest[($#rest+1)/2..$#rest];
    local($i);

    open(FP, ">$fname") || die "write_desired(): error opening output file\n";

				# Header
    print FP "desired = [\n";

				# Write out each goal/level pair.
    for($i = 0; $i <= $#goal; ++$i)
    {
#	print "$i " . $goal[$i] . " " . $level[$i] . "\n";
	print FP ($goal[$i] * $level[$i]) . ";\t" . $level[$i] . ";\n";
    }
				# Also need a random seed.
    print FP "];\n\nrandom_seed = " . rand() . ";\n";

    close FP;
};

#
#  sub translate_weights
#
#  Get the results back from the matlab process and assemble them
# into a weight vector.
#
#
sub translate_weights
{
    local($num, $gain) = @_;
    local($i);
    local($w) = "";
    local($strg, $val);

				# Open the file
    open(FP, ";
				# Header says no solution 
    if(/w no solution/)
    {
				# Log this
	if(defined $parms{"l"})
	{
	    &write_log("translate_weights(): ERROR: NO SOLUTION FOUND BY GRAD.\n");
	};
				# Generate a dummy vector to return
	$w = "0:" x $num;
	close FP;
	return($w);
    };

    if(/w solution/)		# Good header
    {				# Get all the weights
	for($i = 0; $i < $num; ++$i)
	{
	    $strg = ;
	    $strg =~ /([.\d]+)/ || die "translate_weights(): Error parsing data ($strg).\n";
	    $val = $1;
	    $val *= $gain;
	    $w .= $val . ":";
	    if(defined $parms{"l"})
	    {
#		&write_log("$i $val\n");
	    };
	
	};
				# Clean up.
	close FP;
	return($w);
    }
    else			# Unknown header
    {
	die "translate_weights(): Error: can't parse file header ($_).\n";
    };
};

#
#
#  sub compute_weight_vector
#
#  Computes a weight vector given the desired joint positions
# specified in @rest.
#  1.  Generates a matlab-format file that describes the goal
#  2.  Selects the appropriate mcx matrix
#  3.  Forks off a matlab process and waits for the results
#  4.  Reads in the resulting weight file & returns the results.
#
#

sub compute_weight_vector
{
    local($base, $f5_unit, $type, $exp_type, $gain, @rest) = @_;
    local($w);

				# Build the desired vector
    &write_desired("getdesired.m", @rest);

				# Remove the old mcx.m reference so
				#  we can replace it with the one we
				#  need.
    unlink("getmcx.m");
				# Choose one of the mcx matrices 
    symlink($base . ".getmcx." . $type . ".m", "getmcx.m");

				# Go and execute the matlab process
    unless(fork)
    {
	exec("cd mcx; nohup matlab < exec_grad.m >> matlab.log");
    };
    wait;

    $w = &translate_weights($mcx{"num", $exp_type}, $gain);
#    print $w . "\n";
    return($w);
};

#
# sub generate_matlab_mcx_file
#
#  Writes the motor cortex matrices to 3 files , and sets the 
# 'numjoints' variable in each.  The mcx units are split into
# the 3 files according to their type.
#
#
#  The matrix is indexed by:
#   columns are mcx cells
#   odd rows are ( * )
#   even rows are 
#
#

sub generate_matlab_mcx_file
{
    local($base) = @_;
    local($i, $j, $fp);

    open(FP, ">$base.getmcx.p.m") ||
	die "Error opening output file $base.getmcx.p.m\n";

    open(FPF, ">$base.getmcx.f.m") ||
	die "Error opening output file $base.getmcx.f.m\n";

    open(FPIF, ">$base.getmcx.if.m") ||
	die "Error opening output file $base.getmcx.if.m\n";

    open(FPA, ">$base.getmcx.a.m") ||
	die "Error opening output file $base.getmcx.a.m\n";

    print FP "m = [\n";
    print FPF "m = [\n";
    print FPIF "m = [\n";
    print FPA "m = [\n";

    print "size : " . $#JOINTS . " " . $mcx{"num"} . "\n";
    foreach $j (@JOINTS)
    {
#	print "\n\n" . $j . "\n";

				# Write out the prefered position for each
				#   mcx cell for this joint
	for($i = 0; $i < $mcx{"num"}; $i++)
	{
				# Which file does this mcx unit get sent to?
	    if($mcx{"type", $i} eq "p")
	    {
		$fp = FP;
	    }
	    elsif($mcx{"type", $i} eq "f")
	    {
		$fp = FPF;
	    }
	    elsif($mcx{"type", $i} eq "if")
	    {
		$fp = FPIF;
	    }
	    else
	    {
		die "generate_matlab_mcx_file(): bad mcx cell type specified - " .
		    $mcx{"type", $i} . "\n";
	    };

		
				# Defined?
	    if(defined $mcx{"index", $i, $j})
	    {			# Yes

#		print $i . " " . $mcx{"index", $i, $j} . "\n";
		print $fp $mcx{"position", $i, $mcx{"index", $i, $j}}
		    * $mcx{"activity", $i, $mcx{"index", $i, $j}}. "\t";
		print FPA $mcx{"position", $i, $mcx{"index", $i, $j}}
		    * $mcx{"activity", $i, $mcx{"index", $i, $j}}. ",\n";
	    }
	    else
	    {			# No
		print $fp "0\t";
		print FPA "0,\n";
	    };
	};

	print FP "\n";
	print FPF "\n";
	print FPIF "\n";
#	print FPA ";\n";

				# Write out the support level for each
				#  mcx cell for this joint.

	for($i = 0; $i < $mcx{"num"}; $i++)
	{
				# Which file does this mcx unit get sent to?
	    if($mcx{"type", $i} eq "p")
	    {
		$fp = FP;
	    }
	    elsif($mcx{"type", $i} eq "f")
	    {
		$fp = FPF;
	    }
	    elsif($mcx{"type", $i} eq "if")
	    {
		$fp = FPIF;
	    }
	    else
	    {
		die "generate_matlab_mcx_file(): bad mcx cell type specified - " .
		    $mcx{"type", $i} . "\n";
	    };
				# Defined?
	    if(defined $mcx{"index", $i, $j})
	    {			# Yes
		print $fp $mcx{"activity", $i, $mcx{"index", $i, $j}} . "\t";
		print FPA $mcx{"activity", $i, $mcx{"index", $i, $j}} . ",\n";
	    }
	    else
	    {			# No
		print $fp "0\t";
		print FPA "0,\n";
	    };
	};
	print FP "\n";
	print FPF "\n";
	print FPIF "\n";
#	print FPA ";\n";
    };

    print FP "];\n";
    print FPF "];\n";
    print FPIF "];\n";
    print FPA "];\n";

    print FP "\nnumjoints = " . ($#JOINTS+1)  . ";\n\n";
    print FPF "\nnumjoints = " . ($#JOINTS+1)  . ";\n\n";
    print FPIF "\nnumjoints = " . ($#JOINTS+1)  . ";\n\n";
    print FPA "\nnumjoints = " . ($#JOINTS+1)  . ";\n\n";
    
    print FP "\nconnect_prob = " . $F5_MCX_PROB  . ";\n\n";
    print FPF "\nconnect_prob = " . $F5_MCX_PROB  . ";\n\n";
    print FPIF "\nconnect_prob = " . $F5_MCX_PROB  . ";\n\n";
    print FPA "\nconnect_prob = " . $F5_MCX_PROB  . ";\n\n";
    

    close FP;
    close FPF;
    close FPIF;
    close FPA;
};


1;


[ return ]