-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathcf_solo.py
141 lines (109 loc) · 3.99 KB
/
cf_solo.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
141
"""
qfly | Qualisys Drone SDK Example Script: Solo Crazyflie
Takes off, flies circles around Z, Y, X axes.
ESC to land at any time.
"""
import pynput
from time import sleep, time
from qfly import Pose, QualisysCrazyflie, World, utils
# SETTINGS
cf_body_name = 'Crazyflie' # QTM rigid body name
cf_uri = 'radio://0/80/2M/E7E7E7E7E7' # Crazyflie address
cf_marker_ids = [1, 2, 3, 4] # Active marker IDs
circle_radius = 0.5 # Radius of the circular flight path
circle_speed_factor = 0.12 # How fast the Crazyflie should move along circle
# 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
if key == pynput.keyboard.Key.esc:
fly = False
# 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()
# Prepare for liftoff
with QualisysCrazyflie(cf_body_name,
cf_uri,
world,
marker_ids=cf_marker_ids) as qcf:
# Let there be time
t = time()
dt = 0
print("Beginning maneuvers...")
# MAIN LOOP WITH SAFETY CHECK
while(qcf.is_safe()):
# Terminate upon Esc command
if last_key_pressed == pynput.keyboard.Key.esc:
break
# Mind the clock
dt = time() - t
# Calculate Crazyflie's angular position in circle, based on time
phi = circle_speed_factor * dt * 360
# Take off and hover in the center of safe airspace for 5 seconds
if dt < 5:
print(f'[t={int(dt)}] Maneuvering - Center...')
# Set target
target = Pose(world.origin.x, world.origin.y, world.expanse)
# Engage
qcf.safe_position_setpoint(target)
# Move out and circle around Z axis
elif dt < 20:
print(f'[t={int(dt)}] Maneuvering - Circle around Z...')
# Set target
_x, _y = utils.pol2cart(circle_radius, phi)
target = Pose(world.origin.x + _x,
world.origin.y + _y,
world.expanse)
# Engage
qcf.safe_position_setpoint(target)
# Back to center
elif dt < 25:
print(f'[t={int(dt)}] Maneuvering - Center...')
# Set target
target = Pose(world.origin.x, world.origin.y, world.expanse)
# Engage
qcf.safe_position_setpoint(target)
# Move out and circle around Y axis
elif dt < 40:
print(f'[t={int(dt)}] Maneuvering - Circle around X...')
# Set target
_x, _z = utils.pol2cart(circle_radius, phi)
target = Pose(world.origin.x + _x,
world.origin.y,
world.expanse + _z)
# Engage
qcf.safe_position_setpoint(target)
# Back to center
elif dt < 45:
print(f'[t={int(dt)}] Maneuvering - Center...')
# Set target
target = Pose(world.origin.x, world.origin.y, world.expanse)
# Engage
qcf.safe_position_setpoint(target)
# Move and circle around X axis
elif dt < 60:
print(f'[t={int(dt)}] Maneuvering - Circle around X...')
# Set target
_y, _z = utils.pol2cart(circle_radius, phi)
target = Pose(world.origin.x,
world.origin.y + _y,
world.expanse + _z)
# Engage
qcf.safe_position_setpoint(target)
# Back to center
elif dt < 65:
print(f'[t={int(dt)}] Maneuvering - Center...')
# Set target
target = Pose(world.origin.x, world.origin.y, world.expanse)
# Engage
qcf.safe_position_setpoint(target)
else:
break
# Land
while (qcf.pose.z > 0.1):
qcf.land_in_place()