File Coverage

blib/lib/UAV/Pilot/WumpusRover/Server/Backend.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package UAV::Pilot::WumpusRover::Server::Backend;
2 1     1   1175 use v5.14;
  1         2  
  1         29  
3 1     1   1155 use Moose::Role;
  0            
  0            
4              
5             use constant PACKET_METHOD_MAP => {
6             'RequestStartupMessage' => '_packet_request_startup',
7             'RadioTrims' => '_packet_radio_trims',
8             'RadioMins' => '_packet_radio_mins',
9             'RadioMaxes' => '_packet_radio_maxes',
10             'RadioOutputs' => '_packet_radio_out',
11             };
12             my @REQUIRED_PACKET_METHODS = grep {
13             $_ !~ /\A (?:
14             _packet_radio_mins | _packet_radio_maxes
15             ) \z/x
16             } values %{ +PACKET_METHOD_MAP };
17              
18             requires @REQUIRED_PACKET_METHODS;
19             requires qw{
20             ch1_max_out ch1_min_out
21             ch2_max_out ch2_min_out
22             ch3_max_out ch3_min_out
23             ch4_max_out ch4_min_out
24             ch5_max_out ch5_min_out
25             ch6_max_out ch6_min_out
26             ch7_max_out ch7_min_out
27             ch8_max_out ch8_min_out
28             };
29              
30             with 'UAV::Pilot::Logger';
31              
32             has 'started' => (
33             is => 'ro',
34             isa => 'Bool',
35             default => 0,
36             writer => '_set_started',
37             );
38              
39              
40             sub process_packet
41             {
42             my ($self, $packet, $server) = @_;
43              
44             my $packet_class = ref $packet;
45             my ($short_class) = $packet_class =~ /:: (\w+) \z/x;
46              
47             if(! exists $self->PACKET_METHOD_MAP->{$short_class}) {
48             $self->_logger->warn( "Couldn't find a method to handle packet"
49             . " '$short_class'" );
50             return 0;
51             }
52              
53             my $method = $self->PACKET_METHOD_MAP->{$short_class};
54             return $self->$method( $packet, $server );
55             }
56              
57             sub _packet_radio_mins
58             {
59             my ($self, $packet, $server) = @_;
60             foreach (1..8) {
61             my $packet_call = 'ch' . $_ . '_min';
62             my $server_call = '_set_ch' . $_ . '_min';
63              
64             my $value = $packet->$packet_call // 0;
65             $server->$server_call( $value );
66             }
67             return 1;
68             }
69              
70             sub _packet_radio_maxes
71             {
72             my ($self, $packet, $server) = @_;
73             foreach (1..8) {
74             my $packet_call = 'ch' . $_ . '_max';
75             my $server_call = '_set_ch' . $_ . '_max';
76              
77             my $value = $packet->$packet_call // 0;
78             $server->$server_call( $value );
79             }
80             return 1;
81             }
82              
83             #
84             # Implement _map_ch1_value() through _map_ch8_value() here
85             #
86             foreach my $i (1..8) {
87             my $sub_name = '_map_ch' . $i . '_value';
88             my $min_in = 'ch' . $i . '_min';
89             my $max_in = 'ch' . $i . '_max';
90             my $min_out = 'ch' . $i . '_min_out';
91             my $max_out = 'ch' . $i . '_max_out';
92              
93             no strict 'refs';
94             *$sub_name = sub {
95             my ($self, $server, $val) = @_;
96             return $server->_map_value(
97             $server->$min_in,
98             $server->$max_in,
99             $self->$min_out,
100             $self->$max_out,
101             $val,
102             );
103             }
104             }
105              
106              
107             1;
108             __END__
109              
110              
111             =head1 NAME
112              
113             UAV::Pilot::WumpusRover::Server::Backend
114              
115             =head1 DESCRIPTION
116              
117             Role for WumpusRover Backends. A Backend connects directly to the hardware
118             that drives the rover. For instance, the RaspberryPiI2C backend communicates
119             over the Raspberry Pi's I2C interface using a protocol shared by the
120             wumpus_rover Arduino implementation.
121              
122             Does the C<UAV::Pilot::Logger> role.
123              
124             =head1 ATTRIBUTES
125              
126             =head2 started
127              
128             Specifies if this backend has been started yet. Starting it is done by
129             passing a C<RequestStartupMessage> packet to C<process_packet()>.
130              
131              
132             =head1 METHODS
133              
134             =head2 process_packet
135              
136             process_packet( $packet )
137              
138             Takes the packet and does something with it. Usually, this something is a
139             sensible thing to do.
140              
141             =head1 REQUIRED METHODS/ATTRIBUTES
142              
143             =head2 _packet_request_startup
144              
145             _packet_request_startup( $packet, $server )
146              
147             Passed a packet and the server associated with the connection. Handles the
148             initial startup.
149              
150             =head2 _packet_radio_trims
151              
152             _packet_request_trims( $packet, $server )
153              
154             Passed a packet and the server associated with the connection. Handles the
155             radio trims.
156              
157             =head2 _packet_radio_out
158              
159             _packet_request_out( $packet, $server )
160              
161             Passed a packet and the server associated with the connection. Handles the
162             radio outputs, which is the primary way of moving.
163              
164             =head2 _ch*_min_out() and _ch*_max_out()
165              
166             Returns the min/max settings for each channel that will be output by this
167             backend. Channels are numbered 1 through 8.
168              
169             Why do we map the values at this level? For the Arduino output, wouldn't it
170             be better for it to take specified values and convert it to its own output
171             internally? Perhaps. The reason why it was chosen to do the value mapping
172             here is to make the Arduino end as simple-stupid as possible.
173              
174             =cut