File Coverage

blib/lib/DCOLLINS/ANN/Robot.pm
Criterion Covered Total %
statement 8 10 80.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 12 14 85.7


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2             package DCOLLINS::ANN::Robot;
3             BEGIN {
4 3     3   121952 $DCOLLINS::ANN::Robot::VERSION = '0.004';
5             }
6 3     3   31 use strict;
  3         7  
  3         115  
7 3     3   15 use warnings;
  3         8  
  3         95  
8             # ABSTRACT: a wrapper for AI::ANN
9              
10 3     3   1901 use Moose;
  0            
  0            
11             extends 'AI::ANN';
12              
13             use Storable qw(dclone);
14             use Math::Libm qw(erf M_PI tan);
15             #use Memoize;
16             #memoize('_afunc_default');
17             #memoize('_dafunc_default');
18              
19              
20             around BUILDARGS => sub {
21             my $orig = shift;
22             my $class = shift;
23             if (defined $_[0] && ref $_[0] eq 'HASH') {
24             return $class->$orig(%{$_[0]});
25             } elsif (@_ > 0) {
26             my %data = @_;
27             if (exists $data{'data'}) {
28             return $class->$orig(@_);
29             }
30             }
31             my %data = @_;
32             $data{'inputs'} ||= 15;
33             $data{'minvalue'} ||= -2;
34             $data{'maxvalue'} ||= 2;
35             $data{'backprop_eta'} ||= 0.01;
36             ## Pull to center, 0
37             # $data{'afunc'} ||= sub { tan( 2 * (shift) / 3 ) / 2.1 };
38             # $data{'dafunc'} ||= sub { 20/63 / cos( 2 * (shift) / 3 ) ** 2 };
39             ## Pull away from center, 0
40             # $data{'afunc'} ||= \&_afunc_default();
41             # $data{'dafunc'} ||= \&_dafunc_default();
42             $data{'afunc'} ||= sub{_afunc_c(shift)};
43             $data{'dafunc'} ||= sub{_dafunc_c(shift)};
44              
45             ## Pull away from center, 1
46             # $data{'afunc'} ||= sub { erf( 2 * ( (shift) - 1 ) ) + 1};
47             # $data{'dafunc'} ||= sub { 4 / sqrt(M_PI) * exp( -4 * ( (shift) - 1 ) ** 2 ) };
48             my @arg2 = ();
49             for (my $i = 0; $i < 15; $i++) {
50             push @arg2, { 'iamanoutput' => 0,
51             'inputs' => { $i => rand() },
52             'neurons' => [ ],
53             'eta_inputs' => { $i => rand() },
54             'eta_neurons' => [ ] };
55             push @arg2, { 'iamanoutput' => 0,
56             'inputs' => { $i => 3 * rand() - 2 },
57             'neurons' => [ ],
58             'eta_inputs' => { $i => 3 * rand() - 2 },
59             'eta_neurons' => [ ] };
60             } # Made neurons 0-29
61             for (my $i = 0; $i < 15; $i++) {
62             my @working = ();
63             my @eta_working = ();
64             for (my $j = 0; $j < 30; $j ++) {
65             $working[$j] = rand() / 10 - 0.05;
66             $eta_working[$j] = rand() / 10 - 0.05;
67             }
68             push @arg2, { 'iamanoutput' => 0,
69             'inputs' => [],
70             'neurons' => \@working,
71             'eta_inputs' => [],
72             'eta_neurons' => \@eta_working };
73             } # Made neurons 30-44
74             for (my $i = 0; $i < 15; $i++) {
75             my @working = ();
76             my @eta_working = ();
77             for (my $j = 0; $j < 45; $j ++) {
78             $working[$j] = rand() / 10 - 0.05;
79             $eta_working[$j] = rand() / 10 - 0.05;
80             }
81             push @arg2, { 'iamanoutput' => 0,
82             'inputs' => [],
83             'neurons' => \@working,
84             'eta_inputs' => [],
85             'eta_neurons' => \@eta_working };
86             } # Made neurons 45-59
87             for (my $i = 0; $i < 5; $i++) {
88             my @working = ();
89             my @eta_working = ();
90             for (my $j = 30; $j < 60; $j ++) {
91             $working[$j] = rand() / 2 - 0.25;
92             $eta_working[$j] = rand() / 2 - 0.25;
93             }
94             push @arg2, { 'iamanoutput' => 1,
95             'inputs' => [],
96             'neurons' => \@working,
97             'eta_inputs' => [],
98             'eta_neurons' => \@eta_working };
99             } # Made neurons 60-64
100             $data{'data'} = \@arg2;
101             return $class->$orig(%data);
102             };
103              
104             sub _afunc_default {
105             return 2 * erf(shift);
106             }
107             sub _dafunc_default {
108             return 4 / sqrt(M_PI) * exp( -1 * ((shift) ** 2) );
109             }
110              
111             use Inline C => <<'END_C';
112             #include <math.h>
113             double afunc[4001];
114             double dafunc[4001];
115             void generate_globals() {
116             int i;
117             for (i=0;i<=4000;i++) {
118             afunc[i] = 2 * (erf(i/1000.0-2));
119             dafunc[i] = 4 / sqrt(M_PI) * pow(exp(-1 * ((i/1000.0-2))), 2);
120             }
121             }
122             double _afunc_c (float input) {
123             return afunc[(int) floor((input)*1000)+2000];
124             }
125             double _dafunc_c (float input) {
126             return dafunc[(int) floor((input)*1000)+2000];
127             }
128             END_C
129              
130             generate_globals();
131              
132             __PACKAGE__->meta->make_immutable;
133              
134             1;
135              
136             __END__
137             =pod
138              
139             =head1 NAME
140              
141             DCOLLINS::ANN::Robot - a wrapper for AI::ANN
142              
143             =head1 VERSION
144              
145             version 0.004
146              
147             =head1 SYNOPSIS
148              
149             use DCOLLINS::ANN::Robot;
150             my $robot = new DCOLLINS::ANN::Robot ( );
151              
152             =head1 METHODS
153              
154             =head2 new
155              
156             DCOLLINS::ANN::ROBOT::new( )
157              
158             Creates a DCOLLINS::ANN::Robot object and a neural net to go with it.
159              
160             This object has methods of its own, as well as the methods available in AI::ANN. We do, however, override the execute method.
161              
162             For standardization, these are the parameters that SimWorld will pass to the
163             network:
164             Current battery power (0-1)
165             Current pain value (0-1)
166             Differential battery power ((-1)-1)
167             Differential pain value ((-1)-1)
168             Proximity readings, -90, -45, 0, 45, 90 degrees (0-1)
169             Current X location (0-1)
170             Current Y location (0-1)
171             Currently facing: N, S, E, W (0-1)
172              
173             These are the parameters that SimWorld will expect as outputs from the network:
174             Rotate L
175             Rotate R
176             Forwards
177             Reverse
178             Stop
179             The largest value will be accepted. If no output is greater than 1, SimWorld
180             will interpret as a stop.
181              
182             =head1 AUTHOR
183              
184             Dan Collins <dcollin1@stevens.edu>
185              
186             =head1 COPYRIGHT AND LICENSE
187              
188             This software is Copyright (c) 2011 by Dan Collins.
189              
190             This is free software, licensed under:
191              
192             The GNU General Public License, Version 3, June 2007
193              
194             =cut
195