tello 0.0.0 → 0.1.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.
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: []