tello 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7dc54292a6a3a3a5be22cae58d0df97def47d614858be4f5b055064671d9f128
4
- data.tar.gz: fb2ce868969e81c51292ca55d95e4cc31a6c5f48cb862efd52b7874e6e34e2cc
3
+ metadata.gz: 4ca4867953dcdcba813f0d05d3733334bff4ed3360906c3e3222232c117a8119
4
+ data.tar.gz: 36945de880740202f27d70012d00871e8110c94a1312afbcf81190f000c8341d
5
5
  SHA512:
6
- metadata.gz: 59f1da6e31abdfb071654f552b065b60a4f74a059445b97ef3445e2959db01fd81efc83cfe49dd4b2e3d65ee5481f78974fba57b7cc53ff4313a719232d5c074
7
- data.tar.gz: 4b69ec75eed445a7716bf4e68febc3caed4f28972253d4800db6bebf99f5972e59e8209313681a59acc7d4018b0b223407ee7848770406e1899418598b5eac96
6
+ metadata.gz: 36023abd6a254c66336196be4735e2f34df08703f21f079fcb5c72a827844f76d0608d87d20405fb00801c53e604f27d4ca439c10d92017dbc999b38b4a148cc
7
+ data.tar.gz: 3b1b9f4dbe32a9f0d8a1e411b4abd8159969e7cc04328a20dfd3f8555a1b0914ef74db3d9f7fa2214176fb7322cb300b994d77fd837bf7a619830c3caff11ddd
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+ require 'tello/colorize'
3
+ require 'tello/version'
4
+
5
+ # Check Command-line Arguments #################################################
6
+
7
+ usage = "Fly the Tello drone with Ruby!".bold + "\n
8
+ Usage: tello <command> <options>
9
+ [-v|--version]
10
+
11
+ Summary of commands and options:
12
+ console Open an interactive Tello console
13
+ --test Start the console in test mode
14
+ server Start the test server
15
+ -v|--version Prints the installed version\n\n"
16
+
17
+ if ARGV.delete '--test' then $tello_testing = true end
18
+
19
+ case ARGV[0]
20
+ when 'console'
21
+ require 'tello/cli/console'
22
+ when 'server'
23
+ require 'tello/cli/server'
24
+ when '-v', '--version'
25
+ puts Tello::VERSION
26
+ else
27
+ puts usage
28
+ end
@@ -0,0 +1,29 @@
1
+ # Tello module and requires
2
+
3
+ module Tello
4
+ # Flag for testing
5
+ attr_accessor :testing, :os, :ip, :port
6
+
7
+ def self.testing; @testing end
8
+ def self.testing=(t); @testing=(t) end
9
+ def self.os; @os end
10
+
11
+ # Set the operating system
12
+ case RUBY_PLATFORM
13
+ when /darwin/
14
+ @os = :macos
15
+ when /linux/
16
+ @os = :linux
17
+ when /mingw/
18
+ @os = :windows
19
+ end
20
+ end
21
+
22
+ require 'tello/colorize'
23
+ require 'tello/state'
24
+ require 'tello/wifi'
25
+ require 'tello/client'
26
+ require 'tello/dsl'
27
+
28
+ # Add DSL
29
+ extend Tello::DSL
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ if $tello_testing
4
+ puts "⚠️ Test mode enabled"
5
+ r_module = 'tello/cli/testing'
6
+ else
7
+ r_module = 'tello'
8
+ end
9
+
10
+ puts "Ready to receive Tello commands. Type \"exit\" to quit."
11
+
12
+ if system('pry -v &>/dev/null')
13
+ system("pry -r #{r_module}")
14
+ else
15
+ system("irb -r #{r_module}")
16
+ end
@@ -0,0 +1,58 @@
1
+ # A simple UDP server
2
+ require 'tello/colorize'
3
+ require 'socket'
4
+
5
+ PORT = 8889
6
+
7
+ server = UDPSocket.new
8
+ server.bind('localhost', PORT)
9
+
10
+ puts "Starting Tello test server...".bold, "Listening on udp://localhost:#{PORT}"
11
+
12
+ loop do
13
+ msg, addr = server.recvfrom(100)
14
+ puts "#{"==>".green} Received: \"#{msg}\", from #{addr[3]}:#{addr[1]}"
15
+
16
+ case msg
17
+ when 'speed?'
18
+ #=> 1-100 cm/s
19
+ res = "#{rand(1..100).to_f}\r\n"
20
+ when 'battery?'
21
+ #=> 0-100 %
22
+ res = "#{rand(0..100)}\r\n"
23
+ when 'time?'
24
+ #=> time
25
+ res = "#{rand(0..100)}s\r\n"
26
+ when 'height?'
27
+ #=> 0-3000 cm
28
+ res = "#{rand(0..3000)}dm\r\n"
29
+ when 'temp?'
30
+ #=> 0-90 °C
31
+ res = "83~86C\r\n"
32
+ when 'attitude?'
33
+ #=> pitch roll yaw
34
+ res = "pitch:-8;roll:3;yaw:2;\r\n"
35
+ when 'baro?'
36
+ #=> m
37
+ res = "-80.791573\r\n"
38
+ when 'acceleration?'
39
+ #=> x y z
40
+ res = "agx:-138.00;agy:-51.00;agz:-989.00;\r\n"
41
+ when 'tof?'
42
+ #=> 30-1000 cm
43
+ res = "#{rand(30..1000)}mm\r\n"
44
+ when 'wifi?'
45
+ #=> snr
46
+ res = "90\r\n"
47
+ when 'whatever'
48
+ res = "unknown command: whatever"
49
+ else
50
+ #=> 'ok' or 'error'
51
+ res = 'ok'
52
+ end
53
+
54
+ bytes = server.send(res.to_s, 0, addr[3], addr[1])
55
+ puts "#{"<==".blue} Sent: #{res.inspect}, #{bytes} bytes"
56
+ end
57
+
58
+ server.close
@@ -0,0 +1,3 @@
1
+ require 'tello'
2
+
3
+ Tello.testing = true
@@ -0,0 +1,152 @@
1
+ # Tello::Client
2
+ require 'socket'
3
+
4
+ module Tello
5
+ module Client
6
+
7
+ attr_accessor :ip, :port, :connected, :ping, :state
8
+
9
+ class << self
10
+
11
+ # Create a Tello UDP connection
12
+ def connect(ssid = nil)
13
+
14
+ # Connect to Tello wifi
15
+ unless Tello::Wifi.connect(ssid)
16
+ puts "#{'Error:'.error} Could not connect to Tello 😢"
17
+ return false
18
+ end
19
+
20
+ # If already connected, disconnect
21
+ if @connected
22
+ puts "Reconnecting..."
23
+ disconnect
24
+ end
25
+
26
+ # Set IP and port numbers
27
+ @ip = Tello.testing ? 'localhost' : '192.168.10.1'
28
+ @port = 8889
29
+
30
+ # Create UDP client, bind to a previous source IP and port if availble
31
+ @client = UDPSocket.new unless @client
32
+ if @source_ip && @source_port
33
+ @client.bind(@source_ip, @source_port)
34
+ end
35
+
36
+ # Connect to destination, save IP and port assigned by the OS
37
+ @client.connect(@ip, @port)
38
+ @source_ip = @client.addr[3]
39
+ @source_port = @client.addr[1]
40
+
41
+ # Create server to get Tello state
42
+ unless @state_server
43
+ @state_server = UDPSocket.new
44
+ @state_server.bind('0.0.0.0', 8890)
45
+ end
46
+
47
+ # Check to see if test server is up
48
+ if Tello.testing
49
+ print "Connecting to test server..."
50
+ @client.send('command', 0)
51
+ sleep 0.5
52
+ unless read_nonblock
53
+ puts "\n#{'Error:'.error} Could not find Tello test server.",
54
+ "Did you run `tello server` in another terminal window?"
55
+ return false
56
+ end
57
+ puts "connected!"
58
+ end
59
+
60
+ # Tello should be connected over wifi and UDP
61
+ @connected = true
62
+
63
+ # Threads for real Tello connection only
64
+ unless Tello.testing
65
+ # Create thread to keep Tello alive (must recieve command every 15 sec)
66
+ if @ping then @ping.exit end
67
+ @ping = Thread.new do
68
+ loop do
69
+ begin
70
+ @client.send('command', 0)
71
+ rescue Errno::EADDRNOTAVAIL
72
+ puts "#{'Error:'.error} No response from Tello! Try reconnecting."
73
+ @ping.exit
74
+ end
75
+ sleep 15
76
+ end
77
+ end
78
+
79
+ # Get Tello state
80
+ if @state then @state.exit end
81
+ @state = Thread.new do
82
+ loop do
83
+ Tello.store_state(@state_server.recv(256))
84
+ end
85
+ end
86
+ end
87
+
88
+ puts "Ready to fly! 🚁"; true
89
+ end
90
+
91
+ # Get Tello connection status
92
+ def connected?
93
+ if @connected
94
+ true
95
+ else
96
+ puts "Tello is not yet connected. Run `connect` first."
97
+ false
98
+ end
99
+ end
100
+
101
+ # Disconnect the Tello
102
+ def disconnect
103
+ return false unless @connected
104
+ unless Tello.testing
105
+ @state.exit
106
+ @ping.exit
107
+ end
108
+ @client.close
109
+ @client = nil
110
+ @connected = false
111
+ true
112
+ end
113
+
114
+ # Read the UDP response without blocking
115
+ def read_nonblock
116
+ begin
117
+ res = @client.recv_nonblock(256)
118
+ rescue IO::WaitReadable
119
+ res = nil
120
+ rescue Errno::ECONNREFUSED, Errno::EADDRNOTAVAIL
121
+ puts "#{'Error:'.error} Cannot communicate with Tello!"
122
+ @connected
123
+ end
124
+ end
125
+
126
+ # Send a native Tello command string
127
+ def send(cmd)
128
+ return false unless connected?
129
+ while read_nonblock do end # flush previous response data
130
+ @client.send(cmd, 0)
131
+ @client.recv(256).strip
132
+ end
133
+
134
+ # Change 'ok' and 'error' to boolean response instead
135
+ def return_bool(res)
136
+ case res
137
+ when 'ok'
138
+ true
139
+ when 'error'
140
+ false
141
+ end
142
+ end
143
+
144
+ # Change string to number response instead
145
+ def return_num(res)
146
+ if res then res.to_i else res end
147
+ end
148
+
149
+ end
150
+
151
+ end
152
+ end
@@ -0,0 +1,10 @@
1
+ # String#colorize
2
+
3
+ # Extend `String` to include some fancy colors
4
+ class String
5
+ def colorize(c); "\e[#{c}m#{self}\e[0m" end
6
+ def bold; colorize('1') end
7
+ def blue; colorize('1;34') end
8
+ def green; colorize('1;32') end
9
+ def error; colorize('1;31') end
10
+ end
@@ -0,0 +1,207 @@
1
+ # Tello::DSL
2
+ # Define Tello domain-specific language
3
+
4
+ module Tello
5
+ module DSL
6
+
7
+ # Warn Linux and Windows users to manually connect to Wi-Fi, for now
8
+ unless Tello.os == :macos
9
+ puts "Linux and Windows users:".bold,
10
+ " Manually connect to Tello Wi-Fi before running the `connect` command"
11
+ end
12
+
13
+ # Connect to the drone
14
+ def connect
15
+ Tello::Client.connect
16
+ end
17
+
18
+ # Is the drone connected?
19
+ def connected?
20
+ Tello::Client.connected?
21
+ end
22
+
23
+ # Disconnect the drone
24
+ def disconnect
25
+ Tello::Client.disconnect
26
+ end
27
+
28
+ # Send a native Tello command to the drone
29
+ def send(s)
30
+ Tello::Client.send(s)
31
+ end
32
+
33
+ # Check if value is within the common movement range
34
+ def in_move_range?(v)
35
+ (20..500).include? v
36
+ end
37
+
38
+ # Takeoff and land
39
+ [:takeoff, :land].each do |cmd|
40
+ define_method cmd do
41
+ Tello::Client.return_bool send("#{cmd.to_s}")
42
+ end
43
+ end
44
+
45
+ # Move in a given direction
46
+ [:up, :down, :left, :right, :forward, :backward].each do |cmd|
47
+ define_method cmd do |x|
48
+ if in_move_range? x
49
+ Tello::Client.return_bool send("#{cmd.to_s} #{x}")
50
+ else
51
+ puts "Movement must be between 20..500 cm"
52
+ end
53
+ end
54
+ end
55
+
56
+ # Turn clockwise or counterclockwise
57
+ [:cw, :ccw].each do |cmd|
58
+ define_method cmd do |x|
59
+ if (1..3600).include? x
60
+ Tello::Client.return_bool send("#{cmd.to_s} #{x}")
61
+ else
62
+ puts "Rotation must be between 1..3600 degrees"
63
+ end
64
+ end
65
+ end
66
+
67
+ # Flip in a given direction
68
+ def flip(f)
69
+ case f
70
+ when :left, :l
71
+ Tello::Client.return_bool send('flip l')
72
+ when :right, :r
73
+ Tello::Client.return_bool send('flip r')
74
+ when :forward, :f
75
+ Tello::Client.return_bool send('flip f')
76
+ when :backward, :b
77
+ Tello::Client.return_bool send('flip b')
78
+ else
79
+ puts "Not a valid direction to flip"
80
+ false
81
+ end
82
+ end
83
+
84
+ # Get or set the flight speed
85
+ def speed(s = nil)
86
+ if s
87
+ if (10..100).include? s
88
+ Tello::Client.return_bool send("speed #{s}")
89
+ else
90
+ puts "Speed must be between 10..100 cm/s"
91
+ end
92
+ else
93
+ s = send('speed?')
94
+ s == false ? false : s.to_f
95
+ end
96
+ end
97
+
98
+ # Fly to a location in x/y/z coordinates and provided speed
99
+ def go(x, y, z, speed = 10)
100
+
101
+ # Check if coordinates are in range
102
+ unless in_move_range?(x) && in_move_range?(y) && in_move_range?(z)
103
+ puts "x/y/z coordinates must be between 20..500 cm"
104
+ return false
105
+ end
106
+
107
+ # Check if speed is in range
108
+ unless (10..100).include? speed
109
+ puts "Speed must be between 10..100 cm/s"
110
+ return false
111
+ end
112
+
113
+ Tello::Client.return_bool send("go #{x} #{y} #{z} #{speed}")
114
+ end
115
+
116
+ # Fly in a curve; If arc radius is not within 0.5..10 m, command responds false
117
+ def curve(x1, y1, z1, x2, y2, z2, speed = 10)
118
+
119
+ # Check if coordinates are in range
120
+ # TODO: x/y/z can't be between -20..20 at the same time
121
+ unless in_move_range?(x1) && in_move_range?(y1) && in_move_range?(z1) &&
122
+ in_move_range?(x2) && in_move_range?(y2) && in_move_range?(z2)
123
+ puts "x/y/z coordinates must be between 20..500 cm"
124
+ return false
125
+ end
126
+
127
+ # Check if speed is in range
128
+ unless (10..60).include? speed
129
+ puts "Speed must be between 10..60 cm/s"
130
+ return false
131
+ end
132
+
133
+ Tello::Client.return_bool send("curve #{x1} #{y1} #{z1} #{x2} #{y2} #{z2} #{speed}")
134
+ end
135
+
136
+ # Send RC control via four channels:
137
+ # a: left/right, b: forward/backward, c: up/down, d: yaw
138
+ def rc(a, b, c, d)
139
+
140
+ # Check if channel values are in range
141
+ [a, b, c, d].each do |v|
142
+ unless (-100..100).include? v
143
+ puts "RC channel values must be between -100..100"
144
+ return false
145
+ end
146
+ end
147
+
148
+ Tello::Client.return_bool send("rc #{a} #{b} #{c} #{d}")
149
+ end
150
+
151
+ # Get the height of the drone
152
+ def height
153
+ Tello::Client.return_num send('height?')
154
+ end
155
+
156
+ # Get IMU attitude data
157
+ def attitude
158
+ send('attitude?')
159
+ end
160
+
161
+ # Get IMU angular acceleration data
162
+ def acceleration
163
+ send('acceleration?')
164
+ end
165
+
166
+ # Get barometer value
167
+ def baro
168
+ Tello::Client.return_num send('baro?')
169
+ end
170
+
171
+ # Get distance value from TOF
172
+ def tof
173
+ Tello::Client.return_num send('tof?')
174
+ end
175
+
176
+ # Get the flight time
177
+ def time
178
+ Tello::Client.return_num send('time?')
179
+ end
180
+
181
+ # Get the battery level
182
+ def battery
183
+ b = send('battery?')
184
+ b == false ? false : Tello::Client.return_num(b)
185
+ end
186
+
187
+ # Get the temperature of the drone
188
+ def temp
189
+ send('temp?')
190
+ end
191
+
192
+ # Get Wi-Fi signal-to-noise ratio (SNR); if parameters, set SSID and password
193
+ def wifi(ssid: nil, pass: nil)
194
+ if ssid && pass
195
+ Tello::Client.return_bool send("wifi #{ssid} #{pass}")
196
+ else
197
+ Tello::Client.return_num send('wifi?')
198
+ end
199
+ end
200
+
201
+ # Stop all motors immediately
202
+ def stop
203
+ Tello::Client.return_bool send('emergency')
204
+ end
205
+
206
+ end
207
+ end
@@ -0,0 +1,26 @@
1
+ # Tello state
2
+
3
+ module Tello
4
+
5
+ @state
6
+
7
+ class << self
8
+
9
+ # Take a Tello state string, parse to a hash, and store.
10
+ # String in the form:
11
+ # "pitch:11;roll:-18;yaw:118;vgx:0;vgy:0;vgz:0;templ:78;temph:80;tof:10;\
12
+ # h:0;bat:27;baro:-64.81;time:0;agx:242.00;agy:315.00;agz:-1057.00;\r\n"
13
+ def store_state(str)
14
+ str.strip!
15
+ @state = Hash[
16
+ str.split(';').map do |pair|
17
+ k, v = pair.split(':', 2)
18
+ [k.to_sym, v.to_i]
19
+ end
20
+ ]
21
+ end
22
+
23
+ def state; @state end
24
+
25
+ end
26
+ end
@@ -1,5 +1,5 @@
1
1
  # version.rb
2
2
 
3
3
  module Tello
4
- VERSION = '0.0.0'
4
+ VERSION = '0.1.0'
5
5
  end
@@ -0,0 +1,153 @@
1
+ # Tello::Wifi
2
+
3
+ module Tello
4
+ module Wifi
5
+
6
+ attr_accessor :tello_ssid, :macos_airport
7
+
8
+ # Initialize data
9
+ case Tello.os
10
+ when :macos
11
+ @macos_airport = '/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport'
12
+ end
13
+
14
+ class << self
15
+
16
+ # Find and connect to a Tello Wi-Fi
17
+ def connect(ssid = nil)
18
+
19
+ # Skip connecting to Wi-Fi if in test mode
20
+ if Tello.testing
21
+ puts "In test mode, skipping Wi-Fi setup..."
22
+ return true
23
+ end
24
+
25
+ # Assume Wi-Fi manually connected on Linux and Windows, for now
26
+ # TODO: Actually implement
27
+ unless Tello.os == :macos
28
+ return true
29
+ end
30
+
31
+ # If provided SSID, set it, else look for a Tello Wi-Fi
32
+ if ssid
33
+ @tello_ssid = ssid
34
+ else
35
+ # Look for a Tello over Wi-Fi
36
+ print "📶 Looking for Tello Wi-Fi..."
37
+
38
+ # Done if already connected
39
+ if wifi_connected?
40
+ puts "already connected!"
41
+ return true
42
+ end
43
+
44
+ # Search for a Tello Wi-Fi SSID (by default starting with "TELLO-")
45
+ @tello_ssid = get_tello_wifi
46
+
47
+ if @tello_ssid
48
+ puts "found!"
49
+ else
50
+ puts "nothing found"
51
+ return false
52
+ end
53
+ end
54
+
55
+ # Connect to the Tello Wi-Fi
56
+ print "🔗 Connecting to #{@tello_ssid}..."
57
+
58
+ if connect_tello_wifi
59
+ puts "done!"; true
60
+ else
61
+ puts "failed!"; false
62
+ end
63
+ end
64
+
65
+ # Check if already connected to a Tello Wi-Fi, e.g. "TELLO-A5983D"
66
+ def wifi_connected?
67
+ @connected = case Tello.os
68
+ when :macos
69
+ macos_wifi_connected?
70
+ when :linux
71
+ linux_wifi_connected?
72
+ when :windows
73
+ windows_wifi_connected?
74
+ end
75
+ end
76
+
77
+ # macOS `#wifi_connected?`
78
+ def macos_wifi_connected?
79
+ if `#{@macos_airport} -I`.match(/(tello-)\w+/i) then true else false end
80
+ end
81
+
82
+ # Linux `#wifi_connected?`
83
+ def linux_wifi_connected?
84
+ puts "`#linux_connected?` not implemented"; false
85
+ end
86
+
87
+ # Windows `#wifi_connected?`
88
+ def windows_wifi_connected?
89
+ puts "`#windows_connected?` not implemented"; false
90
+ end
91
+
92
+ # Look for a Tello Wi-Fi SSID starting with "TELLO-"
93
+ # Returns an SSID, e.g. "TELLO-B5889D", or `nil` if nothing found
94
+ def get_tello_wifi
95
+ case Tello.os
96
+ when :macos
97
+ macos_get_tello_wifi
98
+ when :linux
99
+ linux_get_tello_wifi
100
+ when :windows
101
+ windows_get_tello_wifi
102
+ end
103
+ end
104
+
105
+ # macOS `#get_tello_wifi`
106
+ def macos_get_tello_wifi
107
+ res = `#{@macos_airport} scan`.match(/(tello-)\w+/i)
108
+ res ? res[0] : nil
109
+ end
110
+
111
+ # Linux `#get_tello_wifi`
112
+ def linux_get_tello_wifi
113
+ puts "`#linux_get_tello_wifi` not implemented"; false
114
+ end
115
+
116
+ # Windows `#get_tello_wifi`
117
+ def windows_get_tello_wifi
118
+ puts "`#windows_get_tello_wifi` not implemented"; false
119
+ end
120
+
121
+ # Connect to an SSID stored in `@tello_ssid`
122
+ def connect_tello_wifi
123
+ case Tello.os
124
+ when :macos
125
+ macos_connect_tello_wifi
126
+ when :linux
127
+ linux_connect_tello_wifi
128
+ when :windows
129
+ windows_connect_tello_wifi
130
+ end
131
+ end
132
+
133
+ # macOS `#connect_tello_wifi`
134
+ def macos_connect_tello_wifi
135
+ # Assumes `en0` is wifi, might have to use this to confirm:
136
+ # networksetup -listallhardwareports
137
+ res = `networksetup -setairportnetwork en0 #{@tello_ssid}`
138
+ res == '' ? true : false
139
+ end
140
+
141
+ # Linux `#connect_tello_wifi`
142
+ def linux_connect_tello_wifi
143
+ puts "`#linux_get_tello_wifi` not implemented"; false
144
+ end
145
+
146
+ # Windows `#connect_tello_wifi`
147
+ def windows_connect_tello_wifi
148
+ puts "`#windows_get_tello_wifi` not implemented"; false
149
+ end
150
+
151
+ end
152
+ end
153
+ end
metadata CHANGED
@@ -1,23 +1,33 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tello
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Black
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-07 00:00:00.000000000 Z
11
+ date: 2018-11-21 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Fly the Tello drone with Ruby.
13
+ description: Fly the Tello drone with Ruby!
14
14
  email: tom@blacktm.com
15
- executables: []
15
+ executables:
16
+ - tello
16
17
  extensions: []
17
18
  extra_rdoc_files: []
18
19
  files:
20
+ - bin/tello
19
21
  - lib/tello.rb
22
+ - lib/tello/cli/console.rb
23
+ - lib/tello/cli/server.rb
24
+ - lib/tello/cli/testing.rb
25
+ - lib/tello/client.rb
26
+ - lib/tello/colorize.rb
27
+ - lib/tello/dsl.rb
28
+ - lib/tello/state.rb
20
29
  - lib/tello/version.rb
30
+ - lib/tello/wifi.rb
21
31
  homepage: https://github.com/blacktm/tello
22
32
  licenses:
23
33
  - MIT
@@ -38,8 +48,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
38
48
  version: '0'
39
49
  requirements: []
40
50
  rubyforge_project:
41
- rubygems_version: 2.7.7
51
+ rubygems_version: 2.7.8
42
52
  signing_key:
43
53
  specification_version: 4
44
- summary: Tello drone control
54
+ summary: Tello
45
55
  test_files: []