argus 0.0.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +25 -1
  4. data/Rakefile +4 -0
  5. data/lib/argus.rb +5 -0
  6. data/lib/argus/ardrone_control_modes.rb +14 -0
  7. data/lib/argus/at_commander.rb +104 -0
  8. data/lib/argus/cad_type.rb +22 -0
  9. data/lib/argus/cfields.rb +80 -0
  10. data/lib/argus/controller.rb +165 -0
  11. data/lib/argus/drone.rb +62 -0
  12. data/lib/argus/float_encoding.rb +13 -0
  13. data/lib/argus/led_animation.rb +48 -0
  14. data/lib/argus/nav_data.rb +78 -0
  15. data/lib/argus/nav_monitor.rb +83 -0
  16. data/lib/argus/nav_option.rb +35 -0
  17. data/lib/argus/nav_option_checksum.rb +20 -0
  18. data/lib/argus/nav_option_demo.rb +79 -0
  19. data/lib/argus/nav_option_unknown.rb +9 -0
  20. data/lib/argus/nav_option_vision_detect.rb +83 -0
  21. data/lib/argus/nav_streamer.rb +111 -0
  22. data/lib/argus/nav_tag.rb +35 -0
  23. data/lib/argus/null_nav_monitor.rb +13 -0
  24. data/lib/argus/pave_parser.rb +39 -0
  25. data/lib/argus/tcp_video_streamer.rb +20 -0
  26. data/lib/argus/time_queue.rb +62 -0
  27. data/lib/argus/udp_sender.rb +13 -0
  28. data/lib/argus/version.rb +10 -0
  29. data/spec/argus/at_commander_spec.rb +82 -0
  30. data/spec/argus/controller_spec.rb +149 -0
  31. data/spec/argus/float_encoding_spec.rb +12 -0
  32. data/spec/argus/led_animation_spec.rb +21 -0
  33. data/spec/argus/nav_data_spec.rb +147 -0
  34. data/spec/argus/nav_option_checksum_spec.rb +21 -0
  35. data/spec/argus/nav_option_demo_spec.rb +56 -0
  36. data/spec/argus/nav_option_spec.rb +32 -0
  37. data/spec/argus/nav_option_unknown_spec.rb +19 -0
  38. data/spec/argus/nav_option_vision_detect_spec.rb +65 -0
  39. data/spec/argus/nav_streamer_spec.rb +111 -0
  40. data/spec/argus/null_nav_monitor_spec.rb +17 -0
  41. data/spec/argus/time_queue_spec.rb +61 -0
  42. data/spec/argus/udp_sender_spec.rb +33 -0
  43. data/spec/spec_helper.rb +13 -0
  44. metadata +51 -12
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2f89d5eb3a36569a8fb2d9e6c17a2eebd17e92d8
4
+ data.tar.gz: ec1b2d028705b04ae55f8eeaa5dfb91c4352347f
5
+ SHA512:
6
+ metadata.gz: 80bde0b4804b76b9be1d79d8c3c2537767a1fc35027bf52811d1324fc4a407d645412ab441675049e2dcf9bdaac14382c5f39fb2520f71e9469dbb4dafe533e9
7
+ data.tar.gz: 330df98c125cfb917f81da99d26dcdc9b25a506e5ffe57ad0c55bc6aad08d035bc2fa6050a377be3f02fe1df58b0d3a1f6e8d587883c5e5753aaba56165244e2
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012 Jim Weirich
1
+ Copyright (c) 2012, 2013 Jim Weirich
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,3 +1,27 @@
1
1
  # Argus -- Parrot AR Drone Ruby API
2
2
 
3
- Coming soon
3
+ ## Current Status
4
+
5
+ * Experimental
6
+ * Subject to change
7
+ * Use at your own risk
8
+ * May cause cancer
9
+
10
+ ## Example
11
+
12
+ <pre>
13
+ require 'argus'
14
+
15
+ drone = Argus::Drone.new
16
+ drone.start
17
+
18
+ drone.take_off
19
+ sleep 5
20
+ drone.turn_right(1.0)
21
+ sleep 5
22
+ drone.turn_left(1.0)
23
+ sleep 5
24
+ drone.hover.land
25
+ sleep 5
26
+ drone.stop
27
+ </pre>
data/Rakefile CHANGED
@@ -7,3 +7,7 @@ task :default => :specs
7
7
  task :specs do
8
8
  sh "rspec spec"
9
9
  end
10
+
11
+ task :land do
12
+ ruby "-Ilib examples/land.rb"
13
+ end
@@ -0,0 +1,5 @@
1
+ # Require all the top level files in argus/*.rb
2
+
3
+ Dir[File.dirname(__FILE__) + "/argus/*.rb"].sort.each do |pn|
4
+ require "argus/#{File.basename(pn, '.rb')}"
5
+ end
@@ -0,0 +1,14 @@
1
+ module Argus
2
+ module ArdroneControlModes
3
+ # ARDRONE_CONTROL_MODE values from the ardrone_api.h file.
4
+
5
+ CFG_GET_CONTROL_MODE = 4 # Send active configuration file
6
+ # to a client through the
7
+ # 'control' socket UDP 5559
8
+
9
+ ACK_CONTROL_MODE = 5 # Reset command mask in navdata
10
+
11
+ CUSTOM_CFG_GET_CONTROL_MODE = 6 # Requests the list of custom
12
+ # configuration IDs
13
+ end
14
+ end
@@ -0,0 +1,104 @@
1
+ require 'thread'
2
+
3
+ module Argus
4
+ class ATCommander
5
+ attr_reader :timestamps
6
+
7
+ def initialize(sender)
8
+ @sender = sender
9
+ @seq = 0
10
+ @ref_data = "0"
11
+ @pcmd_data = "0,0,0,0,0"
12
+ @buffer = ""
13
+ @thread = nil
14
+ @interval = 0.020
15
+ @mutex = Mutex.new
16
+ @timestamps = []
17
+ end
18
+
19
+ def start
20
+ @running = true
21
+ @thread = Thread.new do
22
+ while @running
23
+ log_time
24
+ tick
25
+ sleep @interval
26
+ end
27
+ end
28
+ end
29
+
30
+ def tick
31
+ @mutex.synchronize do
32
+ packet do
33
+ command("REF", @ref_data)
34
+ command("PCMD", @pcmd_data)
35
+ end
36
+ end
37
+ end
38
+
39
+ def stop
40
+ @running = false
41
+ end
42
+
43
+ def join
44
+ @thread.join if @thread
45
+ end
46
+
47
+ def interval=(new_interval)
48
+ @mutex.synchronize do @interval = new_interval end
49
+ end
50
+
51
+ def ref(data)
52
+ @mutex.synchronize do @ref_data = data end
53
+ end
54
+
55
+ def pcmd(data)
56
+ @mutex.synchronize do @pcmd_data = data end
57
+ end
58
+
59
+ def config(key, value)
60
+ @mutex.synchronize do
61
+ command("CONFIG", "\"#{key}\",\"#{value}\"")
62
+ end
63
+ end
64
+
65
+ def comwdg
66
+ @mutex.synchronize do
67
+ command("COMWDG")
68
+ end
69
+ end
70
+ alias reset_watchdog comwdg # For backward compatibility
71
+
72
+ def ctrl(mode)
73
+ @mutex.synchronize do
74
+ command("CTRL", "#{mode},0")
75
+ end
76
+ end
77
+
78
+ private
79
+
80
+ def log_time
81
+ @timestamps.shift if @timestamps.size >= 1000
82
+ @timestamps << Time.now.to_f
83
+ end
84
+
85
+ def packet
86
+ yield self
87
+ flush
88
+ end
89
+
90
+ def flush
91
+ @sender.send_packet(@buffer)
92
+ @buffer = ""
93
+ end
94
+
95
+ def command(name, args=nil)
96
+ @seq += 1
97
+ if args
98
+ @buffer << "AT*#{name}=#{@seq},#{args}\r"
99
+ else
100
+ @buffer << "AT*#{name}=#{@seq}\r"
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,22 @@
1
+ module Argus
2
+ module CadType
3
+
4
+ NAMES = [
5
+ :horizontal, # Deprecated
6
+ :vertical, # Deprecated
7
+ :vision, # Detection of 2D horizontal tags on drone shells
8
+ :none, # Detection disabled
9
+ :cocarde, # Detects a roundel under the drone
10
+ :oriented_cocarde, # Detects an oriented roundel under the drone
11
+ :stripe, # Detects a uniform stripe on the ground
12
+ :h_cocarde, # Detects a roundel in front of the drone
13
+ :h_oriented_cocarde, # Detects an oriented roundel in front of the drone
14
+ :stripe_v,
15
+ :multiple_detection_mode, # The drone uses several detections at the same time
16
+ :cap, # Detects a Cap orange and green in front of the drone
17
+ :oriented_cocarde_bw, # Detects the black and white roundel
18
+ :vision_v2, # Detects 2nd version of shell/tag in front of the drone
19
+ :tower_side, # Detect a tower side with the front camera
20
+ ]
21
+ end
22
+ end
@@ -0,0 +1,80 @@
1
+ require 'argus/float_encoding'
2
+
3
+ module Argus
4
+
5
+ module CFields
6
+ def self.included(base)
7
+ base.send :extend, ClassMethods
8
+ end
9
+
10
+ def initialize(*args)
11
+ super
12
+ @data = unpack_data(args.first)
13
+ end
14
+
15
+ def unpack_data(data)
16
+ @data = data.unpack(self.class.format_string)
17
+ end
18
+
19
+ module ClassMethods
20
+ def data_index
21
+ @data_index ||= 0
22
+ end
23
+
24
+ def format_string
25
+ @format_string ||= (defined?(initial_format) ? initial_format : "")
26
+ end
27
+
28
+ def allot(n=1)
29
+ result = data_index
30
+ @data_index += n
31
+ result
32
+ end
33
+
34
+ def define_field(name, size, format, width=1, &transform)
35
+ if size
36
+ define_array_field(name, size, format, width, transform)
37
+ else
38
+ define_scaler_field(name, format, width, transform)
39
+ end
40
+ end
41
+
42
+ def define_scaler_field(name, format, width, transform)
43
+ index = allot(width)
44
+ format_string << (width==1 ? format : "#{format}#{width}")
45
+ define_method(name) { @data[index] }
46
+ end
47
+
48
+ def define_array_field(name, size, format, width, transform)
49
+ index = allot(width*size)
50
+ format_string << "#{format}#{width*size}"
51
+ define_method(name) { @data[index, width*size] }
52
+ end
53
+
54
+ def uint32_t(name, size=nil)
55
+ define_field(name, size, "V")
56
+ end
57
+
58
+ def uint16_t(name, size=nil)
59
+ define_field(name, size, "v")
60
+ end
61
+
62
+ def float32_t(name, size=nil)
63
+ define_field(name, size, "e")
64
+ end
65
+
66
+ def int32_t(name, size=nil)
67
+ define_field(name, size, "l<")
68
+ end
69
+
70
+ def matrix33_t(name, size=nil)
71
+ define_field(name, size, "V", 9)
72
+ end
73
+
74
+ def vector31_t(name, size=nil)
75
+ define_field(name, size, "V", 3)
76
+ end
77
+ end
78
+ end
79
+
80
+ end
@@ -0,0 +1,165 @@
1
+ require 'argus/float_encoding'
2
+ require 'argus/ardrone_control_modes'
3
+
4
+ module Argus
5
+ class Controller
6
+ include FloatEncoding
7
+
8
+ def initialize(at_commander)
9
+ @at_commander = at_commander
10
+
11
+ @emergency = false
12
+ land
13
+ hover
14
+ end
15
+
16
+ def take_off
17
+ @flying = true
18
+ @emergency = false
19
+ update_ref
20
+ end
21
+
22
+ def land
23
+ @flying = false
24
+ update_ref
25
+ end
26
+
27
+ def emergency
28
+ @flying = false
29
+ @emergency = true
30
+ update_ref
31
+ end
32
+
33
+ def hover
34
+ @moving = false
35
+ @roll = 0.0
36
+ @pitch = 0.0
37
+ @gaz = 0.0
38
+ @yaw = 0.0
39
+ update_pcmd
40
+ end
41
+
42
+ def forward(amount)
43
+ @moving = true
44
+ @pitch = -amount
45
+ update_pcmd
46
+ end
47
+
48
+ def backward(amount)
49
+ @moving = true
50
+ @pitch = amount
51
+ update_pcmd
52
+ end
53
+
54
+ def left(amount)
55
+ @moving = true
56
+ @roll = -amount
57
+ update_pcmd
58
+ end
59
+
60
+ def right(amount)
61
+ @moving = true
62
+ @roll = amount
63
+ update_pcmd
64
+ end
65
+
66
+ def up(amount)
67
+ @moving = true
68
+ @gaz = amount
69
+ update_pcmd
70
+ end
71
+
72
+ def down(amount)
73
+ @moving = true
74
+ @gaz = -amount
75
+ update_pcmd
76
+ end
77
+
78
+ def turn_left(amount)
79
+ @moving = true
80
+ @yaw = -amount
81
+ update_pcmd
82
+ end
83
+
84
+ def turn_right(amount)
85
+ @moving = true
86
+ @yaw = amount
87
+ update_pcmd
88
+ end
89
+
90
+ def led(selection, hertz, duration)
91
+ selection = LedAnimation.lookup_value(selection)
92
+ value = [
93
+ selection,
94
+ FloatEncoding.encode_float(hertz),
95
+ duration
96
+ ].join(',')
97
+ @at_commander.config("leds:leds_anim",value)
98
+ self
99
+ end
100
+
101
+ def enable_detection(colors, type=10, select=32)
102
+ config("detect:enemy_colors",colors.to_s)
103
+ config("detect:detect_type", type.to_s)
104
+ config("detect:detections_select_h", select.to_s)
105
+ self
106
+ end
107
+
108
+ def config(key, value)
109
+ @at_commander.config(key, value)
110
+ end
111
+
112
+ def demo_mode
113
+ @at_commander.config("general:navdata_demo", "TRUE")
114
+ end
115
+
116
+ def front_camera
117
+ @at_commander.config("video:video_channel", "2")
118
+ end
119
+
120
+ def bottom_camera
121
+ @at_commander.config("video:video_channel", "1")
122
+ end
123
+
124
+ def reset_watchdog
125
+ @at_commander.comwdg
126
+ end
127
+
128
+ def ack_control_mode
129
+ @at_commander.ctrl(ArdroneControlModes::ACK_CONTROL_MODE)
130
+ self
131
+ end
132
+
133
+ private
134
+
135
+ REF_BASE = [18, 20, 22, 24, 28].
136
+ inject(0) { |flag, bitnum| flag | (1 << bitnum) }
137
+ REF_FLY_BIT = (1 << 9)
138
+ REF_EMERGENCY_BIT = (1 << 8)
139
+
140
+ def update_ref
141
+ n = REF_BASE
142
+ n |= REF_FLY_BIT if @flying
143
+ n |= REF_EMERGENCY_BIT if @emergency
144
+ @at_commander.ref(n.to_s)
145
+ self
146
+ end
147
+
148
+ def update_pcmd
149
+ flags = 0
150
+ if @moving
151
+ flags = 1
152
+ iroll = encode_float(@roll)
153
+ ipitch = encode_float(@pitch)
154
+ igaz = encode_float(@gaz)
155
+ iyaw = encode_float(@yaw)
156
+ data = "#{flags},#{iroll},#{ipitch},#{igaz},#{iyaw}"
157
+ else
158
+ data = "0,0,0,0,0"
159
+ end
160
+ @at_commander.pcmd(data)
161
+ self
162
+ end
163
+
164
+ end
165
+ end