This blog is also available on Gemini (What's Gemini?)

UAV::Pilot v0.3 Released

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.