argus 0.0.0 → 0.3.0

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.
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