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 +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: []
|