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 +4 -4
- data/bin/tello +28 -0
- data/lib/tello.rb +29 -0
- data/lib/tello/cli/console.rb +16 -0
- data/lib/tello/cli/server.rb +58 -0
- data/lib/tello/cli/testing.rb +3 -0
- data/lib/tello/client.rb +152 -0
- data/lib/tello/colorize.rb +10 -0
- data/lib/tello/dsl.rb +207 -0
- data/lib/tello/state.rb +26 -0
- data/lib/tello/version.rb +1 -1
- data/lib/tello/wifi.rb +153 -0
- metadata +16 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4ca4867953dcdcba813f0d05d3733334bff4ed3360906c3e3222232c117a8119
|
4
|
+
data.tar.gz: 36945de880740202f27d70012d00871e8110c94a1312afbcf81190f000c8341d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36023abd6a254c66336196be4735e2f34df08703f21f079fcb5c72a827844f76d0608d87d20405fb00801c53e604f27d4ca439c10d92017dbc999b38b4a148cc
|
7
|
+
data.tar.gz: 3b1b9f4dbe32a9f0d8a1e411b4abd8159969e7cc04328a20dfd3f8555a1b0914ef74db3d9f7fa2214176fb7322cb300b994d77fd837bf7a619830c3caff11ddd
|
data/bin/tello
ADDED
@@ -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
|
data/lib/tello.rb
CHANGED
@@ -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
|
data/lib/tello/client.rb
ADDED
@@ -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
|
data/lib/tello/dsl.rb
ADDED
@@ -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
|
data/lib/tello/state.rb
ADDED
@@ -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
|
data/lib/tello/version.rb
CHANGED
data/lib/tello/wifi.rb
ADDED
@@ -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.
|
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-
|
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.
|
51
|
+
rubygems_version: 2.7.8
|
42
52
|
signing_key:
|
43
53
|
specification_version: 4
|
44
|
-
summary: Tello
|
54
|
+
summary: Tello
|
45
55
|
test_files: []
|