File Coverage

blib/lib/UAV/Pilot.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;
2 2     2   22051 use v5.14;
  2         6  
  2         86  
3 2     2   2224 use Moose;
  0            
  0            
4             use namespace::autoclean;
5             use File::Spec;
6             use File::ShareDir;
7             use File::HomeDir;
8             use Log::Log4perl;
9              
10             use constant DIST_NAME => 'UAV-Pilot';
11             use constant LOG_CONF_FILE => 'log4perl.conf';
12              
13             our $VERSION = '0.9';
14             our $LOG_WAS_INITD = 0;
15              
16              
17             sub default_module_dir
18             {
19             my ($class) = @_;
20             my $dir = File::ShareDir::dist_dir( $class->DIST_NAME );
21             return $dir;
22             }
23              
24             sub default_config_dir
25             {
26             my ($class) = @_;
27             my $dir = File::HomeDir->my_dist_config( $class->DIST_NAME, {
28             create => 1,
29             });
30             return $dir,
31             }
32              
33             sub init_log
34             {
35             my ($class) = @_;
36             return if $LOG_WAS_INITD;
37             my $conf_dir = $class->default_config_dir;
38             my $log_conf = File::Spec->catfile( $conf_dir, $class->LOG_CONF_FILE );
39              
40             $class->_make_default_log_conf( $log_conf ) if ! -e $log_conf;
41              
42             Log::Log4perl::init( $log_conf );
43             return 1;
44             }
45              
46             sub checksum_fletcher8
47             {
48             my ($class, @bytes) = @_;
49             my $ck_a = 0;
50             my $ck_b = 0;
51              
52             foreach (@bytes) {
53             $ck_a = ($ck_a + $_) & 0xFF;
54             $ck_b = ($ck_b + $ck_a) & 0xFF;
55             }
56              
57             return ($ck_a, $ck_b);
58             }
59              
60             sub convert_32bit_LE
61             {
62             my ($class, @bytes) = @_;
63             my $val = $bytes[0]
64             | ($bytes[1] << 8)
65             | ($bytes[2] << 16)
66             | ($bytes[3] << 24);
67             return $val;
68             }
69              
70             sub convert_16bit_LE
71             {
72             my ($class, @bytes) = @_;
73             my $val = $bytes[0] | ($bytes[1] << 8);
74             return $val;
75             }
76              
77             sub convert_32bit_BE
78             {
79             my ($class, @bytes) = @_;
80             my $val = ($bytes[0] << 24)
81             | ($bytes[1] << 16)
82             | ($bytes[2] << 8)
83             | $bytes[3];
84             return $val;
85             }
86              
87             sub convert_16bit_BE
88             {
89             my ($class, @bytes) = @_;
90             my $val = ($bytes[0] << 8) | $bytes[1];
91             return $val;
92             }
93              
94             sub _make_default_log_conf
95             {
96             my ($class, $out_file) = @_;
97              
98             open( my $out, '>', $out_file )
99             or die "Can't open [$out_file] for writing: $!\n";
100              
101             print $out "log4j.rootLogger=WARN, A1\n";
102             print $out "log4j.appender.A1=Log::Log4perl::Appender::Screen\n";
103             print $out "log4j.appender.A1.layout=org.apache.log4j.PatternLayout\n";
104             print $out "log4j.appender.A1.layout.ConversionPattern="
105             . '%-4r [%t] %-5p %c %t - %m%n' . "\n";
106              
107             close $out;
108             return 1;
109             }
110              
111              
112             no Moose;
113             __PACKAGE__->meta->make_immutable;
114             1;
115             __END__
116              
117             =head1 NAME
118              
119             UAV::Pilot
120              
121             =head1 SYNOPSIS
122              
123             use UAV::Pilot::ARDrone::Driver;
124             use UAV::Pilot::ARDrone::Control;
125            
126             my $ardrone = UAV::Pilot::ARDrone::Driver->new({
127             host => '192.168.1.1',
128             });
129             $ardrone->connect;
130            
131             my $dev = UAV::Pilot::ARDrone::Control->new({
132             sender => $ardrone,
133             });
134            
135            
136             $dev->takeoff;
137             $dev->pitch( 0.5 );
138             $dev->flip_left;
139             $dev->land;
140              
141              
142             =head1 DESCRIPTION
143              
144             Library for controlling Unmanned Aerial Drones.
145              
146              
147             =head1 FIRST FLIGHT OF AR.DRONE
148              
149             =head2 Initial Setup
150              
151             Connect the battery and put on the indoor or outdoor hull (as needed).
152              
153             By default, the AR.Drone starts as its own wireless access point. Configure your wireless
154             network to connect to it.
155              
156             =head2 The Shell
157              
158             The C<uav> program connects to the UAV and prompts for commands. Simply start it and
159             wait for the C<<uav>>> prompt. You can exit by typing C<exit;>, C<quit;>, or C<q;>.
160              
161             The shell takes Perl statements ending with 'C<;>'. Only a basic shell is loaded by
162             default. You must first load the AR.Drone libraries into the system, which you can do with:
163              
164             load 'ARDrone';
165              
166             The ARDrone module will now be loaded. You can now tell it to takeoff, wave, flip, and land.
167              
168             takeoff;
169             wave;
170             flip_left;
171             land;
172              
173             If your drone suddenly stops, has all red lights, and won't takeoff again, then it went into
174             emergency mode. You get it out of this mode with the command:
175              
176             emergency;
177              
178             Which also works to toggle emergency mode back on if your UAV goes out of control.
179              
180             If needed, you can force emergency mode by grabbing the UAV in midair (one hand on top, one
181             on the bottom) and flipping it over.
182              
183             For simple piloting, the commands C<roll/pitch/yaw> can be used. Each of these takes a
184             single parameter of a floating point nubmer between -1.0 and 1.0:
185              
186             roll -0.5;
187             pitch 1.0;
188             yaw 0.25;
189              
190             As you can see, sending a single command only causes the manuever for a brief moment
191             before stopping. Commands must be continuously sent in order to have smooth flight.
192              
193             TODO Write how to send commands continuously once we figure out how
194              
195             =head1 OTHER LINKS
196              
197             L<http://www.wumpus-cave.net> - Developer's blog
198             L<http://projects.ardrone.org> - AR.Drone Open API
199             L<http://ardrone2.parrot.com> - AR.Drone Homepage
200              
201             =head1 LICENSE
202              
203             Copyright (c) 2013, Timm Murray
204             All rights reserved.
205              
206             Redistribution and use in source and binary forms, with or without modification, are
207             permitted provided that the following conditions are met:
208              
209             * Redistributions of source code must retain the above copyright notice, this list of
210             conditions and the following disclaimer.
211             * Redistributions in binary form must reproduce the above copyright notice, this list of
212             conditions and the following disclaimer in the documentation and/or other materials
213             provided with the distribution.
214              
215             THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
216             OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
217             MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
218             COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
219             EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
220             SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
221             HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
222             TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
223             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
224              
225             =cut