-
Notifications
You must be signed in to change notification settings - Fork 384
/
cf.py
140 lines (119 loc) · 5.77 KB
/
cf.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
"""CrazyFlie software-in-the-loop control example.
Setup
-----
Step 1: Clone pycffirmware from https://github.com/utiasDSL/pycffirmware
Step 2: Follow the install instructions for pycffirmware in its README
Example
-------
In terminal, run:
python gym_pybullet_drones/examples/cf.py
"""
import time
import argparse
import numpy as np
import csv
from transforms3d.quaternions import rotate_vector, qconjugate, mat2quat, qmult
from transforms3d.utils import normalized_vector
from gym_pybullet_drones.utils.enums import DroneModel, Physics
from gym_pybullet_drones.envs.CFAviary import CFAviary
from gym_pybullet_drones.control.CTBRControl import CTBRControl
from gym_pybullet_drones.utils.Logger import Logger
from gym_pybullet_drones.utils.utils import sync, str2bool
DEFAULT_DRONES = DroneModel("cf2x")
DEFAULT_PHYSICS = Physics("pyb")
DEFAULT_GUI = True
DEFAULT_PLOT = True
DEFAULT_USER_DEBUG_GUI = False
DEFAULT_SIMULATION_FREQ_HZ = 500
DEFAULT_CONTROL_FREQ_HZ = 25
DEFAULT_OUTPUT_FOLDER = 'results'
NUM_DRONES = 1
INIT_XYZ = np.array([[.5*i, .5*i, .1] for i in range(NUM_DRONES)])
INIT_RPY = np.array([[.0, .0, .0] for _ in range(NUM_DRONES)])
def run(
drone=DEFAULT_DRONES,
physics=DEFAULT_PHYSICS,
gui=DEFAULT_GUI,
plot=DEFAULT_PLOT,
user_debug_gui=DEFAULT_USER_DEBUG_GUI,
simulation_freq_hz=DEFAULT_SIMULATION_FREQ_HZ,
control_freq_hz=DEFAULT_CONTROL_FREQ_HZ,
output_folder=DEFAULT_OUTPUT_FOLDER,
):
#### Create the environment with or without video capture ##
env = CFAviary(drone_model=drone,
num_drones=NUM_DRONES,
initial_xyzs=INIT_XYZ,
initial_rpys=INIT_RPY,
physics=physics,
pyb_freq=simulation_freq_hz,
ctrl_freq=control_freq_hz,
gui=gui,
user_debug_gui=user_debug_gui
)
# ctrl = CTBRControl(drone_model=drone)
#### Obtain the PyBullet Client ID from the environment ####
PYB_CLIENT = env.getPyBulletClient()
#### Initialize the logger #################################
logger = Logger(logging_freq_hz=control_freq_hz,
num_drones=NUM_DRONES,
output_folder=output_folder,
)
#### Run the simulation ####################################
delta = 75 # 3s @ 25hz control loop
trajectory = [[0, 0, 0] for i in range(delta)] + \
[[0, 0, i/delta] for i in range(delta)] + \
[[i/delta, 0, 1] for i in range(delta)] + \
[[1, i/delta, 1] for i in range(delta)] + \
[[1-i/delta, 1, 1] for i in range(delta)] + \
[[0, 1-i/delta, 1] for i in range(delta)] + \
[[0, 0, 1-i/delta] for i in range(delta)]
START = time.time()
for i in range(0, len(trajectory)):
t = i/env.ctrl_freq
#### Step the simulation ###################################
obs, reward, terminated, truncated, info = env.step(i)
for j in range(NUM_DRONES):
try:
target = trajectory[i]
pos = target+[INIT_XYZ[j][0], INIT_XYZ[j][1], 0]
vel = np.zeros(3)
acc = np.zeros(3)
yaw = i*np.pi/delta/2
rpy_rate = np.zeros(3)
env.sendFullStateCmd(pos, vel, acc, yaw, rpy_rate, t)
except:
break
#### Log the simulation ####################################
for j in range(NUM_DRONES):
logger.log(drone=j,
timestamp=i/env.CTRL_FREQ,
state=obs[j]
)
#### Printout ##############################################
env.render()
#### Sync the simulation ###################################
if gui:
pass
sync(i, START, env.CTRL_TIMESTEP)
#### Close the environment #################################
env.close()
#### Save the simulation results ###########################
logger.save()
logger.save_as_csv("beta") # Optional CSV save
#### Plot the simulation results ###########################
if plot:
logger.plot()
if __name__ == "__main__":
#### Define and parse (optional) arguments for the script ##
parser = argparse.ArgumentParser(description='Test flight script using SITL Betaflight')
parser.add_argument('--drone', default=DEFAULT_DRONES, type=DroneModel, help='Drone model (default: BETA)', metavar='', choices=DroneModel)
parser.add_argument('--physics', default=DEFAULT_PHYSICS, type=Physics, help='Physics updates (default: PYB)', metavar='', choices=Physics)
parser.add_argument('--gui', default=DEFAULT_GUI, type=str2bool, help='Whether to use PyBullet GUI (default: True)', metavar='')
parser.add_argument('--plot', default=DEFAULT_PLOT, type=str2bool, help='Whether to plot the simulation results (default: True)', metavar='')
parser.add_argument('--user_debug_gui', default=DEFAULT_USER_DEBUG_GUI, type=str2bool, help='Whether to add debug lines and parameters to the GUI (default: False)', metavar='')
parser.add_argument('--simulation_freq_hz', default=DEFAULT_SIMULATION_FREQ_HZ, type=int, help='Simulation frequency in Hz (default: 500)', metavar='')
parser.add_argument('--control_freq_hz', default=DEFAULT_CONTROL_FREQ_HZ, type=int, help='Control frequency in Hz (default: 25)', metavar='')
parser.add_argument('--output_folder', default=DEFAULT_OUTPUT_FOLDER, type=str, help='Folder where to save logs (default: "results")', metavar='')
ARGS = parser.parse_args()
run(**vars(ARGS))