Skip to content

Instantly share code, notes, and snippets.

@jimweirich
Created May 21, 2013 19:08
Show Gist options
  • Save jimweirich/5622374 to your computer and use it in GitHub Desktop.
Save jimweirich/5622374 to your computer and use it in GitHub Desktop.
Template for creating autonomous drone programs.
# Template for an autonomous drone.
#
# Usage: ruby drone.rb LETTER HOSTNAME
#
# The autonomous drone communciates with the drone manager with a set
# of simple commands. Each command is a single line of text sent over
# a TCP socket connection.
#
# Commands sent by the drone:
#
# name <letter> -- Send the name of the drone to the manager. The
# name should be a single character.
#
# Example: name X
#
# position <x> <y> -- Send the current position of the drone. This
# command should be sent whenever the drone
# changes position. The x and y coordinates
# should be between 1 and 15 (inclusive).
#
# A drone should not move more than 1 space at
# a time (the no teleportation rule), and not
# update the position more than about once a
# second.
#
# Example: position 4 10
#
# The drone should be ready to handle any the the following commands:
#
# name? -- The drone should respond immendiately with the name
# command listed above.
#
# Example: name?
#
# crash! -- Informs the drone that it has crashed. The drone should
# immediately shut down and kill its socket connection.
#
# Example: crash!
#
# radar <x1>,<y1>;<x2>,<y2>;<x3>,<y3> -- List of positions of all
# the known objects in the screen. This may be an empty
# list if the locations of the existing objects is not
# yet known by the drone manager. Note that the drone's
# own position (if known) will be included in the list.
#
# Example: radar 10,3;7,2;5,4
# ---------------------------------------------------------------------
# Some versions of Celluloid want to use sysctl on a Mac to figure out
# the number of CPUs. If you don't have /usr/sbin in your path, then
# leave the following line in to add it automatically. If you are not
# on a Mac, or already have /usr/sbin in your path, then you can
# delete the following line.
ENV['PATH'] = ENV['PATH'] + ":/usr/sbin"
require 'celluloid/io'
class DroneController
include Celluloid::IO
def initialize(name, host=nil)
host = host || 'localhost'
@name = name
@x = rand_coord
@y = rand_coord
@socket = TCPSocket.new(host, 8090)
@running = true
async.run
end
def running?
@running
end
def run
puts "Drone #{@name} flying"
while running? && line = @socket.gets
case line
when /^name\?/
send_data("name #{@name}")
when /^crash!/
puts "Drone #{@name} crashed\n"
@running = false
when /^radar/
# We parse the radar coordinates for you, but don't do
# anything with them. Here would be an interesting place to
# put some custom code.
coords = parse_radar(line)
end
end
@socket.close
end
def parse_radar(line)
line.scan(/(\d+),(\d+)/).map { |x, y|
[x.to_i, y.to_i]
}
end
def rand_coord
(1 + rand * 15.0).to_i
end
def rand_walk(p)
result = p + rand(3) - 1
result = 1 if result < 1
result = 15 if result > 15
result
end
def move
@x = rand_walk(@x)
@y = rand_walk(@y)
send_data("position #{@x} #{@y}\n")
end
def send_data(string)
@socket.puts(string) if running?
end
end
if $0 == __FILE__
name, host = ARGV
if name.nil?
puts "Usage: drone.rb NAME [host]"
exit(1)
end
drone = DroneController.new(name, host)
while drone.running?
sleep 1.0
drone.move
end
end
source 'https://rubygems.org'
gem 'celluloid'
gem 'celluloid-io'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment