flying_robot 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +14 -0
- data/Manifest.txt +29 -0
- data/PostInstall.txt +3 -0
- data/README.rdoc +58 -0
- data/README.txt +58 -0
- data/Rakefile +13 -0
- data/app_generators/flying_robot/USAGE +7 -0
- data/app_generators/flying_robot/flying_robot_generator.rb +75 -0
- data/app_generators/flying_robot/templates/plugins/Hmc6352_compass.rb +56 -0
- data/app_generators/flying_robot/templates/plugins/L293d.rb +27 -0
- data/app_generators/flying_robot/templates/plugins/battery.rb +41 -0
- data/app_generators/flying_robot/templates/plugins/flying_robot.rb +282 -0
- data/app_generators/flying_robot/templates/plugins/maxsonar.rb +80 -0
- data/app_generators/flying_robot/templates/plugins/pololu_ir_receiver.rb +101 -0
- data/app_generators/flying_robot/templates/plugins/pololu_micro_serial_controller.rb +51 -0
- data/app_generators/flying_robot/templates/plugins/pololu_qik_dual_serial_motor_controller.rb +81 -0
- data/app_generators/flying_robot/templates/sketch.rb.erb +81 -0
- data/bin/flying_robot +17 -0
- data/flying_robot.gemspec +36 -0
- data/lib/flying_robot.rb +6 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/flying_robot_spec.rb +11 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +10 -0
- data/tasks/rspec.rake +21 -0
- data/test/test_flying_robot_generator.rb +43 -0
- data/test/test_generator_helper.rb +29 -0
- metadata +98 -0
data/History.txt
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
== 0.0.1 2009-04-03
|
2
|
+
|
3
|
+
* 1 major enhancement:
|
4
|
+
* Initial release
|
5
|
+
|
6
|
+
== 0.0.2 2009-07-08
|
7
|
+
|
8
|
+
* 1 major enhancement:
|
9
|
+
* Plugin support for all hardware included with Blimpduino, including L293D and Maxsonar Ultrasonic range finder
|
10
|
+
|
11
|
+
== 0.0.3 2009-11-14
|
12
|
+
|
13
|
+
* 1 major enhancement:
|
14
|
+
* Update parser for aileron command support
|
data/Manifest.txt
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
PostInstall.txt
|
4
|
+
README.rdoc
|
5
|
+
README.txt
|
6
|
+
Rakefile
|
7
|
+
app_generators/flying_robot/USAGE
|
8
|
+
app_generators/flying_robot/flying_robot_generator.rb
|
9
|
+
app_generators/flying_robot/templates/plugins/Hmc6352_compass.rb
|
10
|
+
app_generators/flying_robot/templates/plugins/battery.rb
|
11
|
+
app_generators/flying_robot/templates/plugins/flying_robot.rb
|
12
|
+
app_generators/flying_robot/templates/plugins/pololu_ir_receiver.rb
|
13
|
+
app_generators/flying_robot/templates/plugins/pololu_micro_serial_controller.rb
|
14
|
+
app_generators/flying_robot/templates/plugins/pololu_qik_dual_serial_motor_controller.rb
|
15
|
+
app_generators/flying_robot/templates/plugins/L293d.rb
|
16
|
+
app_generators/flying_robot/templates/plugins/maxsonar.rb
|
17
|
+
app_generators/flying_robot/templates/sketch.rb.erb
|
18
|
+
bin/flying_robot
|
19
|
+
flying_robot.gemspec
|
20
|
+
lib/flying_robot.rb
|
21
|
+
script/console
|
22
|
+
script/destroy
|
23
|
+
script/generate
|
24
|
+
spec/flying_robot_spec.rb
|
25
|
+
spec/spec.opts
|
26
|
+
spec/spec_helper.rb
|
27
|
+
tasks/rspec.rake
|
28
|
+
test/test_flying_robot_generator.rb
|
29
|
+
test/test_generator_helper.rb
|
data/PostInstall.txt
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
= flying_robot
|
2
|
+
|
3
|
+
http://github.com/deadprogrammer/flying_robot
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
flying_robot takes a standard Ruby Arduino Development (RAD) project, and turns it into a Unmanned Aerial Vehicle (UAV)
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
* Plugins for RAD for cool UAV-related hardware, like Pololu motor controllers and Honeywell digital compass
|
12
|
+
* Complete support for Blimpduino hardware
|
13
|
+
* More plugins coming soon to support other available Arduino-based systems like ArduPilot
|
14
|
+
|
15
|
+
== SYNOPSIS:
|
16
|
+
|
17
|
+
flying_robot takes a standard Ruby Arduino Development (RAD) project, and turns it into a Unmanned Aerial Vehicle (UAV). It includes plugin support for the following hardware:
|
18
|
+
|
19
|
+
* LiPo Battery Voltage
|
20
|
+
* Honeywell HMC6352 Digital Compass
|
21
|
+
* L293D Motor Driver
|
22
|
+
* Maxbotix Maxsonar Ultrasonic Range Finder
|
23
|
+
* Pololu Infrared Detector Array
|
24
|
+
* Pololu Micro Serial Motor Controller
|
25
|
+
* Pololu QIK Dual Serial Motor Controller
|
26
|
+
|
27
|
+
== REQUIREMENTS:
|
28
|
+
|
29
|
+
* sudo gem install rad
|
30
|
+
|
31
|
+
== INSTALL:
|
32
|
+
|
33
|
+
* sudo gem install deadprogrammer-flying_robot
|
34
|
+
|
35
|
+
== LICENSE:
|
36
|
+
|
37
|
+
(The MIT License)
|
38
|
+
|
39
|
+
Copyright (c) 2009 Ron Evans
|
40
|
+
|
41
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
42
|
+
a copy of this software and associated documentation files (the
|
43
|
+
'Software'), to deal in the Software without restriction, including
|
44
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
45
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
46
|
+
permit persons to whom the Software is furnished to do so, subject to
|
47
|
+
the following conditions:
|
48
|
+
|
49
|
+
The above copyright notice and this permission notice shall be
|
50
|
+
included in all copies or substantial portions of the Software.
|
51
|
+
|
52
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
53
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
54
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
55
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
56
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
57
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
58
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.txt
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
= flying_robot
|
2
|
+
|
3
|
+
http://github.com/deadprogrammer/flying_robot
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
flying_robot takes a standard Ruby Arduino Development (RAD) project, and turns it into a Unmanned Aerial Vehicle (UAV)
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
* Plugins for RAD for cool UAV-related hardware, like Pololu motor controllers and Honeywell digital compass
|
12
|
+
* Complete support for Blimpduino hardware
|
13
|
+
* More plugins coming soon to support other available Arduino-based systems like ArduPilot
|
14
|
+
|
15
|
+
== SYNOPSIS:
|
16
|
+
|
17
|
+
flying_robot takes a standard Ruby Arduino Development (RAD) project, and turns it into a Unmanned Aerial Vehicle (UAV). It includes plugin support for the following hardware:
|
18
|
+
|
19
|
+
* LiPo Battery Voltage
|
20
|
+
* Honeywell HMC6352 Digital Compass
|
21
|
+
* L293D Motor Driver
|
22
|
+
* Maxbotix Maxsonar Ultrasonic Range Finder
|
23
|
+
* Pololu Infrared Detector Array
|
24
|
+
* Pololu Micro Serial Motor Controller
|
25
|
+
* Pololu QIK Dual Serial Motor Controller
|
26
|
+
|
27
|
+
== REQUIREMENTS:
|
28
|
+
|
29
|
+
* sudo gem install rad
|
30
|
+
|
31
|
+
== INSTALL:
|
32
|
+
|
33
|
+
* sudo gem install deadprogrammer-flying_robot
|
34
|
+
|
35
|
+
== LICENSE:
|
36
|
+
|
37
|
+
(The MIT License)
|
38
|
+
|
39
|
+
Copyright (c) 2009 Ron Evans
|
40
|
+
|
41
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
42
|
+
a copy of this software and associated documentation files (the
|
43
|
+
'Software'), to deal in the Software without restriction, including
|
44
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
45
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
46
|
+
permit persons to whom the Software is furnished to do so, subject to
|
47
|
+
the following conditions:
|
48
|
+
|
49
|
+
The above copyright notice and this permission notice shall be
|
50
|
+
included in all copies or substantial portions of the Software.
|
51
|
+
|
52
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
53
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
54
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
55
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
56
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
57
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
58
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'hoe'
|
3
|
+
|
4
|
+
Hoe.spec 'flying_robot' do
|
5
|
+
developer('Ron Evans', 'ron dot evans at gmail dot com')
|
6
|
+
|
7
|
+
self.rubyforge_name = 'deadprogrammer'
|
8
|
+
end
|
9
|
+
|
10
|
+
task :cultivate do
|
11
|
+
system "touch Manifest.txt; rake check_manifest | grep -v \"(in \" | patch"
|
12
|
+
system "rake debug_gem | grep -v \"(in \" > `basename \\`pwd\\``.gemspec"
|
13
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
class FlyingRobotGenerator < RubiGen::Base
|
2
|
+
|
3
|
+
DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'],
|
4
|
+
Config::CONFIG['ruby_install_name'])
|
5
|
+
|
6
|
+
default_options :author => nil
|
7
|
+
|
8
|
+
attr_reader :name
|
9
|
+
|
10
|
+
def initialize(runtime_args, runtime_options = {})
|
11
|
+
super
|
12
|
+
usage if args.empty?
|
13
|
+
@destination_root = File.expand_path(args.shift)
|
14
|
+
@name = base_name
|
15
|
+
extract_options
|
16
|
+
end
|
17
|
+
|
18
|
+
def manifest
|
19
|
+
record do |m|
|
20
|
+
# Ensure appropriate folder(s) exists
|
21
|
+
m.directory ''
|
22
|
+
BASEDIRS.each { |path| m.directory path }
|
23
|
+
|
24
|
+
# create stub
|
25
|
+
m.template 'sketch.rb.erb' , "#{base_name}.rb"
|
26
|
+
|
27
|
+
# copy plugins
|
28
|
+
m.file "plugins/battery.rb", "vendor/plugins/battery.rb"
|
29
|
+
m.file "plugins/flying_robot.rb", "vendor/plugins/flying_robot.rb"
|
30
|
+
m.file "plugins/Hmc6352_compass.rb", "vendor/plugins/Hmc6352_compass.rb"
|
31
|
+
m.file "plugins/pololu_ir_receiver.rb", "vendor/plugins/pololu_ir_receiver.rb"
|
32
|
+
m.file "plugins/pololu_micro_serial_controller.rb", "vendor/plugins/pololu_micro_serial_controller.rb"
|
33
|
+
m.file "plugins/pololu_qik_dual_serial_motor_controller.rb", "vendor/plugins/pololu_qik_dual_serial_motor_controller.rb"
|
34
|
+
m.file "plugins/L293d.rb", "vendor/plugins/L293d.rb"
|
35
|
+
m.file "plugins/maxsonar.rb", "vendor/plugins/maxsonar.rb"
|
36
|
+
|
37
|
+
m.dependency "install_rubigen_scripts", [destination_root, 'flying_robot'],
|
38
|
+
:shebang => options[:shebang], :collision => :force
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
def banner
|
44
|
+
<<-EOS
|
45
|
+
Creates a ...
|
46
|
+
|
47
|
+
USAGE: #{spec.name} name
|
48
|
+
EOS
|
49
|
+
end
|
50
|
+
|
51
|
+
def add_options!(opts)
|
52
|
+
opts.separator ''
|
53
|
+
opts.separator 'Options:'
|
54
|
+
# For each option below, place the default
|
55
|
+
# at the top of the file next to "default_options"
|
56
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
57
|
+
# "Some comment about this option",
|
58
|
+
# "Default: none") { |o| options[:author] = o }
|
59
|
+
opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
60
|
+
end
|
61
|
+
|
62
|
+
def extract_options
|
63
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
64
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
65
|
+
# raw instance variable value.
|
66
|
+
# @author = options[:author]
|
67
|
+
end
|
68
|
+
|
69
|
+
# Installation skeleton. Intermediate directories are automatically
|
70
|
+
# created so don't sweat their absence here.
|
71
|
+
BASEDIRS = %w(
|
72
|
+
vendor/plugins
|
73
|
+
examples
|
74
|
+
)
|
75
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# Plugin for Ruby Arduino Development that allows use of the HMC6352 Compass module
|
2
|
+
# Written by Ron Evans (http://deadprogrammersociety.com) for the flying_robot project
|
3
|
+
#
|
4
|
+
# Based on code taken from the SparkFun forums: http://forum.sparkfun.com/viewtopic.php?t=6236
|
5
|
+
class Hmc6352Compass < ArduinoPlugin
|
6
|
+
include_wire
|
7
|
+
|
8
|
+
external_variables "int HMC6352Address = 0x42"
|
9
|
+
external_variables "byte headingData[2]"
|
10
|
+
external_variables "int headingValue = 0"
|
11
|
+
|
12
|
+
# Shift the device's documented slave address (0x42) 1 bit right
|
13
|
+
# This compensates for how the TWI library only wants the
|
14
|
+
# 7 most significant bits (with the high bit padded with 0)
|
15
|
+
# This results in 0x21 as the address to pass to TWI
|
16
|
+
external_variables "int slaveAddress = HMC6352Address >> 1"
|
17
|
+
|
18
|
+
void prepare_compass() {
|
19
|
+
// hack to reference plugin, copied this trick from twitter plugin
|
20
|
+
}
|
21
|
+
|
22
|
+
// The whole number part of the heading
|
23
|
+
int heading()
|
24
|
+
{
|
25
|
+
return int (headingValue / 10) ;
|
26
|
+
}
|
27
|
+
|
28
|
+
// The fractional part of the heading
|
29
|
+
int heading_fractional()
|
30
|
+
{
|
31
|
+
return int (headingValue % 10) ;
|
32
|
+
}
|
33
|
+
|
34
|
+
void read_compass()
|
35
|
+
{
|
36
|
+
// Send a "A" command to the HMC6352
|
37
|
+
// This requests the current heading data
|
38
|
+
Wire.beginTransmission(slaveAddress);
|
39
|
+
Wire.send("A"); // The "Get Data" command
|
40
|
+
Wire.endTransmission();
|
41
|
+
delay(10); // The HMC6352 needs at least a 70us (microsecond) delay
|
42
|
+
// after this command. Using 10ms just makes it safe
|
43
|
+
// Read the 2 heading bytes, MSB first
|
44
|
+
// The resulting 16bit word is the compass heading in 10ths of a degree
|
45
|
+
// For example: a heading of 1345 would be 134.5 degrees
|
46
|
+
Wire.requestFrom(slaveAddress, 2); // Request the 2 byte heading (MSB comes first)
|
47
|
+
int i = 0;
|
48
|
+
while(Wire.available() && i < 2)
|
49
|
+
{
|
50
|
+
headingData[i] = Wire.receive();
|
51
|
+
i++;
|
52
|
+
}
|
53
|
+
headingValue = headingData[0]*256 + headingData[1]; // Put the MSB and LSB together
|
54
|
+
}
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Plugin for Ruby Arduino Development that allows use of the L293D motor controller
|
2
|
+
# Written by Ron Evans (http://deadprogrammersociety.com) for the flying_robot project
|
3
|
+
#
|
4
|
+
#
|
5
|
+
# Adapted from code written by Jordi Muñoz for the Blimpduino project
|
6
|
+
# http://blimpduino.googlecode.com/svn/trunk/Motors.pde
|
7
|
+
#
|
8
|
+
class L293d < ArduinoPlugin
|
9
|
+
plugin_directives "#define FORWARD 1"
|
10
|
+
plugin_directives "#define REVERSE 0"
|
11
|
+
|
12
|
+
void L293_send_command(int directionPin, int speedPin, byte direction, byte speed)
|
13
|
+
{
|
14
|
+
direction = constrain(direction, 0, 1);
|
15
|
+
speed = constrain(speed, 0, 127);
|
16
|
+
|
17
|
+
if (direction == FORWARD) {
|
18
|
+
digitalWrite(directionPin, LOW);
|
19
|
+
analogWrite(speedPin, speed);
|
20
|
+
} else {
|
21
|
+
speed = 255 - speed ;
|
22
|
+
digitalWrite(directionPin, HIGH);
|
23
|
+
analogWrite(speedPin, speed);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# Plugin for Ruby Arduino Development that reads a battery voltage from a power source that has been connected
|
2
|
+
# to one of the Arduino's analog pins. Note that you probably need to reduce the voltage considerably with a resistor (10K value?)
|
3
|
+
# before feeding it to the analog pin. You should also add another 10K resistor as a pull-down from the pin to ground.
|
4
|
+
#
|
5
|
+
# Written by Ron Evans (http://deadprogrammersociety.com) for the flying_robot project
|
6
|
+
# http://github.com/deadprogrammer/flying_robot
|
7
|
+
#
|
8
|
+
# Adapted from code written by Jordi Muñoz for the Blimpduino project
|
9
|
+
# http://code.google.com/p/blimpduino/source/browse/trunk/BlimpDuino_v4.pde)
|
10
|
+
#
|
11
|
+
class Battery < ArduinoPlugin
|
12
|
+
external_variables "float average_battery = 0.0"
|
13
|
+
external_variables "bool battery_init_completed"
|
14
|
+
|
15
|
+
add_to_setup "battery_init_completed = false;"
|
16
|
+
|
17
|
+
# bogus function here to make RAD happy
|
18
|
+
void battery_test() {
|
19
|
+
}
|
20
|
+
|
21
|
+
// initialize the battery reading
|
22
|
+
void init_battery(int pin) {
|
23
|
+
average_battery = analogRead(pin);
|
24
|
+
}
|
25
|
+
|
26
|
+
// get the current voltage
|
27
|
+
// TODO: allow user to set constants for different expected battery voltages
|
28
|
+
float voltage(int pin)
|
29
|
+
{
|
30
|
+
if (! battery_init_completed) {
|
31
|
+
init_battery(pin);
|
32
|
+
}
|
33
|
+
|
34
|
+
average_battery=(((float) average_battery * 0.99) + (float)((float) analogRead(pin) * 0.01)); // Jordi called it dynamic average
|
35
|
+
|
36
|
+
float battery_voltage=(float)((float) average_battery * (float)4.887586) * (float)2; // converting values to millivolts..,
|
37
|
+
|
38
|
+
return battery_voltage ;
|
39
|
+
}
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,282 @@
|
|
1
|
+
# Plugin for Ruby Arduino Development that parses the flying_robot command set from any source of input to the serial port
|
2
|
+
# Written by Ron Evans (http://deadprogrammersociety.com) for the flying_robot project
|
3
|
+
#
|
4
|
+
# In order to implement a sketch that uses the flying_robot parser, you need to implement the methods that make up its interface
|
5
|
+
# so that it will respond to the standard command set.
|
6
|
+
#
|
7
|
+
# The following commands are supported:
|
8
|
+
# (h)ail - See if the UAV can still respond. Should send "Roger" back.
|
9
|
+
# (s)tatus - Grab a snapshot of all instrument readings plus any other status info that the UAV can support
|
10
|
+
# (e)levators - Set the elevators. The command supports two parameters:
|
11
|
+
# direction - enter 'u' for up, 'c' for centered, or 'd' for down
|
12
|
+
# deflection - enter an angle between 0 and 90 degrees
|
13
|
+
# (r)udder - Set the rudder. This command supports two parameters:
|
14
|
+
# direction - enter 'l' for left, 'c' for centered, or 'r' for right
|
15
|
+
# deflection - enter an angle between 0 and 90 degrees
|
16
|
+
# (a)ilerons - Set the ailerons. This command supports two parameters:
|
17
|
+
# direction - enter 'l' for left, 'c' for centered, or 'r' for right
|
18
|
+
# deflection - enter an angle between 0 and 90 degrees
|
19
|
+
# (t)hrottle - Set the throttle. This command supports two parameters:
|
20
|
+
# direction - enter 'f' for forward, or 'r' for reverse
|
21
|
+
# speed - enter a percentage from 0 to 100
|
22
|
+
# (i)nstruments - Read the current data for one of the installed instruments on the UAV. This command supports one parameter:
|
23
|
+
# id - enter an integer for which instrment readings should be returned from. If there is not an instrument installed
|
24
|
+
# for that id 'Invalid instrument' will be returned
|
25
|
+
# (p)rogram - Engage whatever autopilot program is available, if any. This command supports one parameter:
|
26
|
+
# id - enter an integer for which autopilot routine should be used. Enter 0 to cancel autopilot
|
27
|
+
#
|
28
|
+
class FlyingRobot < ArduinoPlugin
|
29
|
+
# used for parsing input commands
|
30
|
+
external_variables "bool current_command_received_complete"
|
31
|
+
external_variables "int current_command_length"
|
32
|
+
external_variables "char command_buffer[120]"
|
33
|
+
|
34
|
+
# the parsed command
|
35
|
+
external_variables "char command_code[1]"
|
36
|
+
external_variables "char direction_code[1]"
|
37
|
+
external_variables "char instrument_code[1]"
|
38
|
+
external_variables "char autopilot_code[1]"
|
39
|
+
external_variables "int command_value"
|
40
|
+
|
41
|
+
# current elevator values
|
42
|
+
external_variables "char elevator_direction[1]"
|
43
|
+
external_variables "int elevator_deflection = 0"
|
44
|
+
|
45
|
+
# current rudder values
|
46
|
+
external_variables "char rudder_direction[1]"
|
47
|
+
external_variables "int rudder_deflection = 0"
|
48
|
+
|
49
|
+
# current aileron values
|
50
|
+
external_variables "char aileron_direction[1]"
|
51
|
+
external_variables "int aileron_deflection = 0"
|
52
|
+
|
53
|
+
# current throttle values
|
54
|
+
external_variables "char throttle_direction[1]"
|
55
|
+
external_variables "int throttle_speed = 0"
|
56
|
+
|
57
|
+
# autopilot
|
58
|
+
external_variables "bool autopilot_engaged"
|
59
|
+
|
60
|
+
# initialize parser vars
|
61
|
+
add_to_setup "current_command_received_complete = false; elevator_direction[0] = 'c'; rudder_direction[0] = 'c'; throttle_direction[0] = 'f'; autopilot_engaged = false;"
|
62
|
+
|
63
|
+
# this is a hack to get the plugin included, that I got from the twitter_connect example
|
64
|
+
void be_flying_robot(){}
|
65
|
+
|
66
|
+
boolean current_command_received_is_complete() {
|
67
|
+
return current_command_received_complete == true ;
|
68
|
+
}
|
69
|
+
|
70
|
+
char current_command() {
|
71
|
+
return command_code[0];
|
72
|
+
}
|
73
|
+
|
74
|
+
char current_command_direction() {
|
75
|
+
return direction_code[0];
|
76
|
+
}
|
77
|
+
|
78
|
+
char current_command_instrument() {
|
79
|
+
return instrument_code[0];
|
80
|
+
}
|
81
|
+
|
82
|
+
char current_command_autopilot() {
|
83
|
+
return autopilot_code[0];
|
84
|
+
}
|
85
|
+
|
86
|
+
int current_command_value() {
|
87
|
+
return command_value ;
|
88
|
+
}
|
89
|
+
|
90
|
+
char current_elevator_direction() {
|
91
|
+
return elevator_direction[0];
|
92
|
+
}
|
93
|
+
|
94
|
+
int current_elevator_deflection() {
|
95
|
+
return elevator_deflection ;
|
96
|
+
}
|
97
|
+
|
98
|
+
char current_aileron_direction() {
|
99
|
+
return aileron_direction[0];
|
100
|
+
}
|
101
|
+
|
102
|
+
int current_aileron_deflection() {
|
103
|
+
return aileron_deflection ;
|
104
|
+
}
|
105
|
+
|
106
|
+
char current_rudder_direction() {
|
107
|
+
return rudder_direction[0];
|
108
|
+
}
|
109
|
+
|
110
|
+
int current_rudder_deflection() {
|
111
|
+
return rudder_deflection ;
|
112
|
+
}
|
113
|
+
|
114
|
+
char current_throttle_direction() {
|
115
|
+
return throttle_direction[0];
|
116
|
+
}
|
117
|
+
|
118
|
+
int current_throttle_speed() {
|
119
|
+
return throttle_speed ;
|
120
|
+
}
|
121
|
+
|
122
|
+
boolean is_autopilot_on() {
|
123
|
+
return autopilot_engaged == true ;
|
124
|
+
}
|
125
|
+
|
126
|
+
void autopilot_on() {
|
127
|
+
autopilot_engaged = true;
|
128
|
+
}
|
129
|
+
|
130
|
+
void autopilot_off() {
|
131
|
+
autopilot_engaged = false;
|
132
|
+
}
|
133
|
+
|
134
|
+
void clear_command_buffer() {
|
135
|
+
for(int i=0; i<120; i++){
|
136
|
+
command_buffer[i] = 0 ;
|
137
|
+
}
|
138
|
+
|
139
|
+
command_code[0] = 0 ;
|
140
|
+
direction_code[0] = 0 ;
|
141
|
+
instrument_code[0] = 0 ;
|
142
|
+
current_command_length = 0 ;
|
143
|
+
current_command_received_complete = false ;
|
144
|
+
}
|
145
|
+
|
146
|
+
void parse_command_code() {
|
147
|
+
if(current_command_length == 0) {
|
148
|
+
command_code[0] = 0;
|
149
|
+
} else {
|
150
|
+
command_code[0] = command_buffer[0];
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
154
|
+
void parse_direction_code() {
|
155
|
+
if(current_command_length >= 3) {
|
156
|
+
direction_code[0] = command_buffer[2];
|
157
|
+
} else {
|
158
|
+
direction_code[0] = 0;
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
162
|
+
void parse_instrument_code() {
|
163
|
+
if(current_command_length >= 3) {
|
164
|
+
instrument_code[0] = command_buffer[2];
|
165
|
+
} else {
|
166
|
+
instrument_code[0] = 0;
|
167
|
+
}
|
168
|
+
}
|
169
|
+
|
170
|
+
void parse_autopilot_code() {
|
171
|
+
if(current_command_length >= 3) {
|
172
|
+
autopilot_code[0] = command_buffer[2];
|
173
|
+
} else {
|
174
|
+
autopilot_code[0] = 0;
|
175
|
+
}
|
176
|
+
}
|
177
|
+
|
178
|
+
void parse_command_value(int start) {
|
179
|
+
if(current_command_length >= start + 1) {
|
180
|
+
command_value = atoi(command_buffer + start);
|
181
|
+
} else {
|
182
|
+
command_value = 0 ;
|
183
|
+
}
|
184
|
+
}
|
185
|
+
|
186
|
+
void get_command() {
|
187
|
+
if(current_command_received_complete) {
|
188
|
+
clear_command_buffer();
|
189
|
+
}
|
190
|
+
|
191
|
+
while(Serial.available() > 0) {
|
192
|
+
command_buffer[current_command_length] = Serial.read();
|
193
|
+
if(command_buffer[current_command_length] == '\r') {
|
194
|
+
current_command_received_complete = true ;
|
195
|
+
parse_command_code();
|
196
|
+
return;
|
197
|
+
} else {
|
198
|
+
current_command_length++ ;
|
199
|
+
}
|
200
|
+
}
|
201
|
+
}
|
202
|
+
|
203
|
+
// used to echo the commands being received via serial
|
204
|
+
void print_current_command(const char* cmd, int val) {
|
205
|
+
Serial.print(cmd);
|
206
|
+
Serial.print(" command - direction:");
|
207
|
+
Serial.print(current_command_direction());
|
208
|
+
Serial.print(" value:");
|
209
|
+
Serial.println(val);
|
210
|
+
}
|
211
|
+
|
212
|
+
void dispatch_command() {
|
213
|
+
if(!current_command_received_is_complete()) {
|
214
|
+
return;
|
215
|
+
}
|
216
|
+
|
217
|
+
char cmd = current_command();
|
218
|
+
|
219
|
+
if (cmd == 'h') {
|
220
|
+
hail();
|
221
|
+
} else if (cmd == 's') {
|
222
|
+
status();
|
223
|
+
} else if (cmd == 'e') {
|
224
|
+
parse_direction_code();
|
225
|
+
parse_command_value(4);
|
226
|
+
elevator_direction[0] = current_command_direction();
|
227
|
+
elevator_deflection = current_command_value();
|
228
|
+
if (elevator_deflection > 90) {
|
229
|
+
elevator_deflection = 90 ;
|
230
|
+
}
|
231
|
+
|
232
|
+
elevators();
|
233
|
+
} else if (cmd == 'r') {
|
234
|
+
parse_direction_code();
|
235
|
+
parse_command_value(4);
|
236
|
+
rudder_direction[0] = current_command_direction();
|
237
|
+
rudder_deflection = current_command_value();
|
238
|
+
if (rudder_deflection > 90) {
|
239
|
+
rudder_deflection = 90 ;
|
240
|
+
}
|
241
|
+
|
242
|
+
rudder();
|
243
|
+
} else if (cmd == 'a') {
|
244
|
+
parse_direction_code();
|
245
|
+
parse_command_value(4);
|
246
|
+
aileron_direction[0] = current_command_direction();
|
247
|
+
aileron_deflection = current_command_value();
|
248
|
+
if (aileron_deflection > 90) {
|
249
|
+
aileron_deflection = 90 ;
|
250
|
+
}
|
251
|
+
|
252
|
+
ailerons();
|
253
|
+
} else if (cmd == 't') {
|
254
|
+
parse_direction_code();
|
255
|
+
parse_command_value(4);
|
256
|
+
throttle_direction[0] = current_command_direction();
|
257
|
+
throttle_speed = current_command_value();
|
258
|
+
if (throttle_speed > 100) {
|
259
|
+
throttle_speed = 100 ;
|
260
|
+
}
|
261
|
+
|
262
|
+
throttle();
|
263
|
+
} else if (cmd == 'i') {
|
264
|
+
parse_instrument_code();
|
265
|
+
instruments();
|
266
|
+
} else if (cmd == 'p') {
|
267
|
+
parse_autopilot_code();
|
268
|
+
if (autopilot_code[0] == '0') {
|
269
|
+
autopilot_off();
|
270
|
+
}
|
271
|
+
|
272
|
+
autopilot();
|
273
|
+
} else {
|
274
|
+
Serial.println("Invalid command");
|
275
|
+
}
|
276
|
+
}
|
277
|
+
|
278
|
+
void process_command() {
|
279
|
+
get_command();
|
280
|
+
dispatch_command();
|
281
|
+
}
|
282
|
+
end
|