-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathcf_multi.py
140 lines (111 loc) · 3.81 KB
/
cf_multi.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
"""
qfly | Qualisys Drone SDK Example Script: Multi Crazyflie
Drones take off and fly circles around Z axis.
ESC to land at any time.
"""
import pynput
from time import sleep, time
from qfly import Pose, QualisysCrazyflie, World, ParallelContexts, utils
import numpy as np
# SETTINGS
# QTM rigid body names
cf_body_names = [
'Crazyflie1',
'Crazyflie2'
]
# Crazyflie addresses
cf_uris = [
'radio://0/80/2M/E7E7E7E701',
'radio://0/80/2M/E7E7E7E702'
]
# Crazyflie marker ids
cf_marker_ids = [
[11, 12, 13, 14],
[21, 22, 23, 24]
]
# Watch key presses with a global variable
last_key_pressed = None
# Set up keyboard callback
def on_press(key):
"""React to keyboard."""
global last_key_pressed
last_key_pressed = key
# Listen to the keyboard
listener = pynput.keyboard.Listener(on_press=on_press)
listener.start()
# Set up world - the World object comes with sane defaults
world = World()
# Stack up context managers
_qcfs = [QualisysCrazyflie(cf_body_name,
cf_uri,
world,
marker_ids=cf_marker_id)
for cf_body_name, cf_uri, cf_marker_id
in zip(cf_body_names, cf_uris, cf_marker_ids)]
with ParallelContexts(*_qcfs) as qcfs:
# Let there be time
t = time()
dt = 0
print("Beginning maneuvers...")
# "fly" variable used for landing on demand
fly = True
# MAIN LOOP WITH SAFETY CHECK
while(fly and all(qcf.is_safe() for qcf in qcfs)):
# Land with Esc
if last_key_pressed == pynput.keyboard.Key.esc:
break
# Mind the clock
dt = time() - t
# Cycle all drones
for idx, qcf in enumerate(qcfs):
# Take off and hover in the center of safe airspace
if dt < 3:
print(f'[t={int(dt)}] Maneuvering - Center...')
# Set target
x = np.interp(idx,
[0,
len(qcfs) - 1],
[world.origin.x - world.expanse / 2,
world.origin.x + world.expanse / 2])
target = Pose(x,
world.origin.y,
world.expanse)
# Engage
qcf.safe_position_setpoint(target)
sleep(0.02)
# Move out half of the safe airspace in the X direction and circle around Z axis
elif dt < 30:
print(f'[t={int(dt)}] Maneuvering - Circle around Z...')
# Set target
phi = (dt * 90) % 360 # Calculate angle based on time
# Offset angle based on array
phi = phi + 360 * (idx / len(qcfs))
_x, _y = utils.pol2cart(0.5, phi)
target = Pose(world.origin.x + _x,
world.origin.y + _y,
world.expanse)
# Engage
qcf.safe_position_setpoint(target)
sleep(0.02)
# Back to center
elif dt < 33:
print(f'[t={int(dt)}] Maneuvering - Center...')
# Set target
x = np.interp(idx,
[0,
len(qcfs) - 1],
[world.origin.x - world.expanse / 2,
world.origin.x + world.expanse / 2])
target = Pose(x,
world.origin.y,
world.expanse)
# Engage
qcf.safe_position_setpoint(target)
sleep(0.02)
else:
fly = False
# Land
while (qcf.pose.z > 0.1):
for idx, qcf in enumerate(qcfs):
qcf.land_in_place()
sleep(0.02)