# # 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;