flying_robot 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,80 @@
1
+ # Plugin for Ruby Arduino Development that allows use of the Maxbotix MaxSonar ultrasonic range finder
2
+ # Written by Ron Evans (http://deadprogrammersociety.com) for the flying_robot project
3
+ #
4
+ # Based on code taken from the Blimpduino project: http://code.google.com/p/blimpduino/source/browse/trunk/Ultrasonic_Sensor.pde
5
+ class Maxsonar < ArduinoPlugin
6
+ external_variables "unsigned long maxsonar_refresh_rate = 1000"
7
+ external_variables "unsigned long maxsonar_last_reading_time = 0"
8
+ external_variables "long last_maxsonar_distance = 0"
9
+ external_variables "int ping_rx"
10
+ external_variables "bool maxsonar_init_complete"
11
+
12
+ add_to_setup "maxsonar_init_complete = false;"
13
+
14
+ long maxsonar_distance () {
15
+ return last_maxsonar_distance ;
16
+ }
17
+
18
+ void reset_maxsonar() {
19
+ maxsonar_last_reading_time = millis();
20
+ }
21
+
22
+ void init_maxsonar(int reset_pin) {
23
+ if (maxsonar_init_complete) {
24
+ return ;
25
+ }
26
+
27
+ delay(250);
28
+ digitalWrite(reset_pin, HIGH);
29
+ delay(100);
30
+ last_maxsonar_distance = 0;
31
+ maxsonar_init_complete = true ;
32
+ }
33
+
34
+ int read_maxsonar(int an_pin) {
35
+ int dist = 0 ;
36
+ dist = analogRead(an_pin);
37
+ dist = (dist / 2);
38
+ return dist;
39
+ }
40
+
41
+ void update_maxsonar(int an_pin, int reset_pin) {
42
+ init_maxsonar(reset_pin);
43
+
44
+ if (millis() - maxsonar_last_reading_time > maxsonar_refresh_rate) {
45
+ last_maxsonar_distance = read_maxsonar(an_pin);
46
+ }
47
+ }
48
+
49
+ void init_maxsonar_pw(int reset_pin) {
50
+ if (maxsonar_init_complete) {
51
+ return ;
52
+ }
53
+
54
+ last_maxsonar_distance = 0;
55
+ digitalWrite(reset_pin, HIGH);
56
+ digitalWrite(reset_pin, LOW); // Activating MCU internal pull-down resistor
57
+ digitalWrite(reset_pin, HIGH);
58
+ delay(1000);
59
+ maxsonar_init_complete = true ;
60
+ }
61
+
62
+ int read_maxsonar_pw(int pw_pin) {
63
+ long pulse_length=0; //declaring variable
64
+ digitalWrite(ping_rx, HIGH);
65
+ delay(37);
66
+ pulse_length=pulseIn(pw_pin, HIGH); //pulseIn function to mesure the lenght of the pulse
67
+ digitalWrite(ping_rx, LOW);
68
+ pulse_length = (pulse_length / 147);
69
+ return pulse_length;
70
+ }
71
+
72
+ void update_maxsonar_pw(int pw_pin, int reset_pin) {
73
+ init_maxsonar_pw(reset_pin);
74
+
75
+ if (millis() - maxsonar_last_reading_time > maxsonar_refresh_rate) {
76
+ last_maxsonar_distance = read_maxsonar_pw(pw_pin);
77
+ }
78
+ }
79
+
80
+ end
@@ -0,0 +1,101 @@
1
+ # Plugin for Ruby Arduino Development that allows use of the Pololu IR Receiver Beacons
2
+ # Written by Ron Evans (http://deadprogrammersociety.com) for the flying_robot project
3
+ #
4
+ # Based on code taken from the Blimpduino project: http://code.google.com/p/blimpduino/source/browse/trunk/InfraRed.pde
5
+ class PololuIrReceiver < ArduinoPlugin
6
+ external_variables "unsigned long ir_count[4]"
7
+ external_variables "int ir_beacon_direction = 0"
8
+ external_variables "unsigned long ir_beacon_refresh_rate = 500"
9
+ external_variables "unsigned long ir_beacon_last_reading_time = 0"
10
+
11
+ plugin_directives "#define IR_BEACON_NOT_FOUND 0"
12
+ plugin_directives "#define IR_BEACON_FORWARD 1"
13
+ plugin_directives "#define IR_BEACON_RIGHT 2"
14
+ plugin_directives "#define IR_BEACON_BACK 3"
15
+ plugin_directives "#define IR_BEACON_LEFT 4"
16
+
17
+ # this function returns either 0, meaning the IR beacon was not found
18
+ # or else 1 = Forward, 2 = Right, 3 = Back, 4 = Left
19
+ int current_ir_beacon_direction() {
20
+ return ir_beacon_direction ;
21
+ }
22
+
23
+ boolean ir_beacon_not_detected() {
24
+ return ir_beacon_direction == IR_BEACON_NOT_FOUND ;
25
+ }
26
+
27
+ boolean ir_beacon_forward() {
28
+ return ir_beacon_direction == IR_BEACON_FORWARD ;
29
+ }
30
+
31
+ boolean ir_beacon_right() {
32
+ return ir_beacon_direction == IR_BEACON_RIGHT ;
33
+ }
34
+
35
+ boolean ir_beacon_back() {
36
+ return ir_beacon_direction == IR_BEACON_BACK ;
37
+ }
38
+
39
+ boolean ir_beacon_left() {
40
+ return ir_beacon_direction == IR_BEACON_LEFT ;
41
+ }
42
+
43
+ void reset_ir_receiver() {
44
+ ir_count[0] = 0 ;
45
+ ir_count[1] = 0 ;
46
+ ir_count[2] = 0 ;
47
+ ir_count[3] = 0 ;
48
+ ir_beacon_last_reading_time = millis();
49
+ }
50
+
51
+ void finalize_ir_reading()
52
+ {
53
+ ir_beacon_direction = 0 ;
54
+
55
+ if(ir_count[0] + ir_count[1] + ir_count[2] + ir_count[3] > 10) {
56
+ if(ir_count[1]>ir_count[0]) // counter 1 (right IR sensor) is greater than the counter 0 (forward ir sensor)
57
+ {
58
+ ir_beacon_direction|=0x01; // set the bit 1 in high (0b00000001)
59
+ } // if not leave it in cero (0b0000000).
60
+
61
+ if(ir_count[3]>ir_count[2]) // the counter 3 (left IR sensor) is greater than the counter 2 (back ir sensor)..
62
+ {
63
+ ir_beacon_direction|=0x02; // Put the second bit of the variable in HIGH example: 0b00000010
64
+ } // i f not leave it in cero.. 0b00000000
65
+
66
+ if(ir_count[(ir_beacon_direction&0x01)] > ir_count[((ir_beacon_direction>>1)+2)]) // Now compare the to greatest counters either counter 0 or 1, vs. 2 or 3,
67
+ {
68
+ ir_beacon_direction&=0x01; //If yes, store the position of the > value, but eliminate the second bit and leave the first bit untouched..
69
+ }
70
+ else
71
+ {
72
+ ir_beacon_direction=((ir_beacon_direction>>1)+2); //Eliminate the first bit and plus two...
73
+ }
74
+
75
+ ir_beacon_direction++;
76
+ }
77
+
78
+ reset_ir_receiver();
79
+ }
80
+
81
+ void update_ir_receiver(int front_pin, int right_pin, int back_pin, int left_pin) {
82
+ if (millis() - ir_beacon_last_reading_time > ir_beacon_refresh_rate) {
83
+ finalize_ir_reading();
84
+ } else {
85
+ if (digitalRead(front_pin) == LOW) {
86
+ ir_count[0]++;
87
+ }
88
+ if (digitalRead(right_pin) == LOW) {
89
+ ir_count[1]++;
90
+ }
91
+ if (digitalRead(back_pin) == LOW) {
92
+ ir_count[2]++;
93
+ }
94
+ if (digitalRead(left_pin) == LOW) {
95
+ ir_count[3]++;
96
+ }
97
+ }
98
+ }
99
+
100
+
101
+ end
@@ -0,0 +1,51 @@
1
+ # Plugin for Ruby Arduino Development that allows use of the Pololu micro dual serial motor controller
2
+ # Written by Ron Evans (http://deadprogrammersociety.com) for the flying_robot project
3
+ #
4
+ # This is the device this plugin works with:
5
+ # http://www.pololu.com/catalog/product/410
6
+ #
7
+ # Based on code taken from the Pololu forums: http://forum.pololu.com/viewtopic.php?f=15&t=1102&p=4913&hilit=arduino#p4913
8
+ class PololuMicroSerialController < ArduinoPlugin
9
+ plugin_directives "#define LEFT_MOTOR 2"
10
+ plugin_directives "#define RIGHT_MOTOR 3"
11
+
12
+ plugin_directives "#define FORWARD 1"
13
+ plugin_directives "#define REVERSE 0"
14
+
15
+ external_variables "bool mc_init_complete"
16
+ add_to_setup "mc_init_complete = false;"
17
+
18
+ void pmsc_init(int motor_controller_reset_pin)
19
+ {
20
+ if (mc_init_complete) {
21
+ return ;
22
+ }
23
+
24
+ mc_init_complete = true ;
25
+
26
+ // start up motor controller
27
+ digitalWrite(motor_controller_reset_pin, LOW);
28
+ delay(10);
29
+ digitalWrite(motor_controller_reset_pin, HIGH);
30
+
31
+ // let motor controller wake up
32
+ delay(100);
33
+ }
34
+
35
+ void pmsc_send_command(SoftwareSerial& motor_controller, byte motor, byte direction, byte speed)
36
+ {
37
+ unsigned char mc_command[4];
38
+ direction = constrain(direction, 0, 1);
39
+ speed = constrain(speed, 0, 127);
40
+
41
+ mc_command[0] = 0x80; // start byte
42
+ mc_command[1] = 0x00; // Device type byte
43
+ mc_command[2] = (2 * motor) + (direction == FORWARD ? FORWARD : REVERSE); // Motor number and direction byte
44
+ mc_command[3] = speed; // Motor speed (0 to 127)
45
+
46
+ // send data
47
+ for(int i = 0; i < 4; i++)
48
+ { motor_controller.print(mc_command[i], BYTE); }
49
+ }
50
+
51
+ end
@@ -0,0 +1,81 @@
1
+ # Plugin for Ruby Arduino Development that allows use of the Pololu Qik 2s9v1 Serial controller
2
+ # Written by Ron Evans (http://deadprogrammersociety.com) for the flying_robot project
3
+ #
4
+ # This is the device this plugin works with:
5
+ # http://www.pololu.com/catalog/product/1110
6
+ # It may work with other Pololu motor controllers, but is NOT compatible with the Micro Serial Controller's command set
7
+ #
8
+ class PololuQikDualSerialMotorController < ArduinoPlugin
9
+ plugin_directives "#define LEFT_MOTOR 2"
10
+ plugin_directives "#define RIGHT_MOTOR 3"
11
+
12
+ plugin_directives "#define FORWARD 1"
13
+ plugin_directives "#define REVERSE 0"
14
+
15
+ external_variables "bool mc_init_complete"
16
+ add_to_setup "mc_init_complete = false;"
17
+
18
+ void qik_init(int motor_controller_reset_pin, SoftwareSerial& motor_controller)
19
+ {
20
+ if (mc_init_complete) {
21
+ return ;
22
+ }
23
+
24
+ mc_init_complete = true ;
25
+
26
+ // start up motor controller
27
+ digitalWrite(motor_controller_reset_pin, LOW);
28
+ delay(10);
29
+ digitalWrite(motor_controller_reset_pin, HIGH);
30
+
31
+ // let motor controller wake up
32
+ delay(100);
33
+
34
+ // turn off Pololu auto-disable on errors
35
+ unsigned char mc_command[7];
36
+ mc_command[0] = 0xAA; // start command
37
+ mc_command[1] = 0x09; // device number
38
+ mc_command[2] = 0x04; // set configuration parameter
39
+ mc_command[3] = 0x02; // Shutdown Motors on Error
40
+ mc_command[4] = 0x00; // do not shutdown
41
+ mc_command[5] = 0x55; // command terminator
42
+ mc_command[6] = 0x2A; // end command
43
+
44
+ // send data
45
+ for(int i = 0; i < 7; i++)
46
+ { motor_controller.print(mc_command[i], BYTE); }
47
+
48
+ delay(10);
49
+ }
50
+
51
+ void qik_send_command(SoftwareSerial& motor_controller, byte motor, byte direction, byte speed)
52
+ {
53
+ unsigned char mc_command[4];
54
+ direction = constrain(direction, 0, 1);
55
+ speed = constrain(speed, 0, 127);
56
+
57
+ mc_command[0] = 0xAA;
58
+ mc_command[1] = 0x09;
59
+
60
+ if (motor == LEFT_MOTOR) {
61
+ if (direction == FORWARD) {
62
+ mc_command[2] = 0x88; // M0 forward
63
+ } else {
64
+ mc_command[2] = 0x8A; // M0 reverse
65
+ }
66
+ } else {
67
+ if (direction == FORWARD) {
68
+ mc_command[2] = 0x8C; // M1 forward
69
+ } else {
70
+ mc_command[2] = 0x8E; // M2 reverse
71
+ }
72
+ }
73
+
74
+ mc_command[3] = speed; // Motor speed (0 to 127)
75
+
76
+ // send data
77
+ for(int i = 0; i < 4; i++)
78
+ { motor_controller.print(mc_command[i], BYTE); }
79
+ }
80
+
81
+ end
@@ -0,0 +1,81 @@
1
+ # <%= base_name %>
2
+ #
3
+ # Uses Ruby Arduino Development to create Unmanned Aerial Vehicles
4
+ # Written by Ron Evans (http://deadprogrammersociety.com)
5
+ # Based on flying_robot library (http://flyingrobo.com)
6
+ #
7
+ # This sketch that uses the flying_robot parser, you just need to implement the methods that make up its interface
8
+ # so that it will respond to the standard command set.
9
+ #
10
+ # The following commands are supported:
11
+ # (h)ail - See if the UAV can still respond. Should send "Roger" back.
12
+ # (s)tatus - Grab a snapshot of all instrument readings plus any other status info that the UAV can support
13
+ # (e)levators - Set the elevators. The command supports two parameters:
14
+ # direction - enter 'u' for up, 'c' for centered, or 'd' for down
15
+ # deflection - enter an angle between 0 and 90 degrees
16
+ # (r)udder - Set the rudder. 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
+ # (a)ilerons - Set the ailerons. This command supports two parameters:
20
+ # direction - enter 'l' for left, 'c' for centered, or 'r' for right
21
+ # deflection - enter an angle between 0 and 90 degrees
22
+ # (t)hrottle - Set the throttle. This command supports two parameters:
23
+ # direction - enter 'f' for forward, or 'r' for reverse
24
+ # speed - enter a percentage from 0 to 100
25
+ # (i)nstruments - Read the current data for one of the installed instruments on the UAV. This command supports one parameter:
26
+ # id - enter an integer for which instrment readings should be returned from. If there is not an instrument installed
27
+ # for that id 'Invalid instrument' will be returned
28
+ # (p)rogram - Engage whatever autopilot program is available, if any. This command supports one parameter:
29
+ # id - enter an integer for which autopilot routine should be used. Enter 0 to cancel autopilot
30
+ #
31
+ class <%= base_name.camelize -%> < ArduinoSketch
32
+ serial_begin :rate => 9600
33
+
34
+ # main command loop, required for any arduino program
35
+ def loop
36
+ be_flying_robot
37
+ process_command
38
+ end
39
+
40
+ # flying robot interface, implement these for your own hardware set
41
+ def hail
42
+ serial_println "Roger"
43
+ end
44
+
45
+ def status
46
+ serial_println "Status: operational"
47
+ end
48
+
49
+ def elevators
50
+ print_current_command("Elevators", current_elevator_deflection)
51
+ end
52
+
53
+ def ailerons
54
+ print_current_command("Ailerons", current_ailerons_deflection)
55
+ end
56
+
57
+ def rudder
58
+ print_current_command("Rudder", current_rudder_deflection)
59
+ end
60
+
61
+ def throttle
62
+ print_current_command("Throttle", current_throttle_speed)
63
+ end
64
+
65
+ def instruments
66
+ serial_print "Instruments command - request:"
67
+ serial_println current_command_instrument
68
+ end
69
+
70
+ def autopilot
71
+ if current_command_autopilot == '0'
72
+ # autopilot cancel
73
+ serial_println "Autopilot Is Off"
74
+ end
75
+
76
+ if current_command_autopilot == '1'
77
+ autopilot_on
78
+ serial_println "Autopilot Is On"
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'rubigen'
5
+
6
+ if %w(-v --version).include? ARGV.first
7
+ require 'flying_robot/version'
8
+ puts "#{File.basename($0)} #{FlyingRobot::VERSION}"
9
+ exit(0)
10
+ end
11
+
12
+ require 'rubigen/scripts/generate'
13
+ source = RubiGen::PathSource.new(:application,
14
+ File.join(File.dirname(__FILE__), "../app_generators"))
15
+ RubiGen::Base.reset_sources
16
+ RubiGen::Base.append_sources source
17
+ RubiGen::Scripts::Generate.new.run(ARGV, :generator => 'flying_robot')
@@ -0,0 +1,36 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "flying_robot"
5
+ s.version = "0.0.3"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Ron Evans"]
9
+ s.date = %q{2009-11-15}
10
+ s.default_executable = %q{flying_robot}
11
+ s.description = %q{flying_robot takes a standard Ruby Arduino Development (RAD) project, and turns it into a Unmanned Aerial Vehicle (UAV)}
12
+ s.email = ["ron dot evans at gmail dot com"]
13
+ s.executables = ["flying_robot"]
14
+ s.extra_rdoc_files = ["History.txt", "Manifest.txt", "PostInstall.txt", "README.txt"]
15
+ s.files = ["History.txt", "Manifest.txt", "PostInstall.txt", "README.rdoc", "README.txt", "Rakefile", "app_generators/flying_robot/USAGE", "app_generators/flying_robot/flying_robot_generator.rb", "app_generators/flying_robot/templates/plugins/Hmc6352_compass.rb", "app_generators/flying_robot/templates/plugins/battery.rb", "app_generators/flying_robot/templates/plugins/flying_robot.rb", "app_generators/flying_robot/templates/plugins/pololu_ir_receiver.rb", "app_generators/flying_robot/templates/plugins/pololu_micro_serial_controller.rb", "app_generators/flying_robot/templates/plugins/pololu_qik_dual_serial_motor_controller.rb", "app_generators/flying_robot/templates/plugins/L293d.rb", "app_generators/flying_robot/templates/plugins/maxsonar.rb", "app_generators/flying_robot/templates/sketch.rb.erb", "bin/flying_robot", "flying_robot.gemspec", "lib/flying_robot.rb", "script/console", "script/destroy", "script/generate", "spec/flying_robot_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/rspec.rake", "test/test_flying_robot_generator.rb", "test/test_generator_helper.rb"]
16
+ s.homepage = %q{http://github.com/deadprogrammer/flying_robot}
17
+ s.rdoc_options = ["--main", "README.txt"]
18
+ s.require_paths = ["lib"]
19
+ s.rubyforge_project = %q{deadprogrammer}
20
+ s.rubygems_version = %q{1.3.5}
21
+ s.summary = %q{flying_robot takes a standard Ruby Arduino Development (RAD) project, and turns it into a Unmanned Aerial Vehicle (UAV)}
22
+ s.test_files = ["test/test_flying_robot_generator.rb", "test/test_generator_helper.rb"]
23
+
24
+ if s.respond_to? :specification_version then
25
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
26
+ s.specification_version = 3
27
+
28
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
29
+ s.add_development_dependency(%q<hoe>, [">= 2.3.3"])
30
+ else
31
+ s.add_dependency(%q<hoe>, [">= 2.3.3"])
32
+ end
33
+ else
34
+ s.add_dependency(%q<hoe>, [">= 2.3.3"])
35
+ end
36
+ end