2013-06-17
Version 0.3 of UAV::Pilot has been released on CPAN. The major change in this version is an improved event loop based on AnyEvent.
AnyEvent is a very nice framework overall, but unfortunately doesn't have quite the right syntax for UAV::Pilot's purposes. Consider this plain-English description of a UAV flight:
Takeoff, wait 5 seconds, then pitch forward for 2 seconds, then pitch backwards for 2 seconds, then land
In AnyEvent's standard interface, things would work out something like this:
my $timer; $timer = AnyEvent->timer( after => 5, cb => sub { $uav->pitch( -1.0 ); my $timer2; $timer2 = AnyEvent->timer( after => 2, cb => sub { $uav->pitch( 1.0 ); my $timer3; $timer3 = AnyEvent->timer( after => 2, cb => sub { $uav->land; $cv->send; }, ); $timer2; }, ); $timer; }, );
$uav->takeoff; $cv->recv;
All that indentation gets hairy. So I created an interface on top of AnyEvent, UAV::Pilot::EasyEvent, which is based on the Node.js event interface used by NodeCopter[1]. Here's how you'd write the same problem using EasyEvent:
my $cv = AnyEvent->condvar; my $event = UAV::Pilot::EasyEvent->new({ condvar => $cv, });
$event ->add_timer( duration => 2000, duration_units => $event->UNITS_MILLISECOND, cb => sub { $uav->pitch( -1.0 ) }, )->add_timer( duration => 2000, duration_units => $event->UNITS_MILLISECOND, cb => sub { $uav->pitch( 1.0 ) }, )->add_timer( duration => 2000, duration_units => $event->UNITS_MILLISECOND, cb => sub { $uav->land; $cv->send; }, );
$event->activate_events; $uav->takeoff; $cv->recv;
Much better.
As an added bonus, having a good event interface means we can also support controlling UAVs through SDL joysticks. See bin/uav_joysticks in the distribution for details.