Paparazzi UAS
v7.1_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
simple_quad_sim.py
Go to the documentation of this file.
1
import
pybullet
as
p
2
import
pybullet_data
3
import
numpy
as
np
4
import
time
5
import
os
6
7
8
PPRZ_HOME =
os.getenv
(
"PAPARAZZI_HOME"
,
os.getcwd
())
9
PYBULLET_CONF_PATH =
os.path.join
(PPRZ_HOME,
"conf/simulator/pybullet"
)
10
11
12
class
BulletFDM
():
13
def
__init__
(self, dt=0.02, GUI=True, debug=False, urdf="robobee.urdf"):
14
print(f
"Hello from PyBullet ! dt={dt}, GUI={GUI} debug={debug}"
)
15
16
pprz_src =
os.getenv
(
"PAPARAZZI_SRC"
)
17
print(f
"pprz_src = {pprz_src}"
)
18
19
# self.last_time_print = 0
20
21
# dt : Time step
22
self.
dt
=dt
23
if
GUI:
24
self.
physicsClient
=
p.connect
(
p.GUI
)
25
else
:
26
self.
physicsClient
=
p.connect
(
p.DIRECT
)
27
p.configureDebugVisualizer
(
p.COV_ENABLE_GUI
,0)
# remove useless graphical elements from GUI
28
29
# Add path for pybullet assests e.g : plane and grid...
30
p.setAdditionalSearchPath
(
pybullet_data.getDataPath
())
31
32
self.
planeId
=
p.loadURDF
(
"plane.urdf"
)
33
self.
textureId
=
p.loadTexture
(
"checker_grid.jpg"
)
34
35
self.
vehicle_start_pos
= [0, 0, 0.2]
36
self.
vehicle_start_orientation
=
p.getQuaternionFromEuler
([0, 0, 0])
37
38
vehicule_urdf =
os.path.join
(PYBULLET_CONF_PATH, urdf)
39
self.
vehicle
=
p.loadURDF
(vehicule_urdf, self.
vehicle_start_pos
, self.
vehicle_start_orientation
)
40
41
# Bullet physics uses ENU frame
42
p.setGravity
(0, 0, -9.81, physicsClientId=self.
physicsClient
)
43
# Real time simulation should be off in order to apply external force and moments !
44
p.setRealTimeSimulation
(0, physicsClientId=self.
physicsClient
)
45
# dt : Time step
46
p.setTimeStep
(self.
dt
, physicsClientId=self.
physicsClient
)
47
# Orient the camera if needed
48
p.resetDebugVisualizerCamera
( cameraDistance=3.5, cameraYaw=-80, cameraPitch=-40, cameraTargetPosition=[0.0, 0.0, 0.0])
49
# Vehicle properties
50
self.
KF
= 0.01 ; self.KM = 0.001
51
# Initialte velocity and acceleration vectors
52
self.
vel
=
np.zeros
(3)
53
self.
accel
=
np.zeros
(3)
54
# Initialte angular velocity and acceleration vectors
55
self.
ang_vel
=
np.zeros
(3)
56
self.
ang_accel
=
np.zeros
(3)
57
58
# State
59
self.
observation
= {}
60
61
# For debug purposes
62
if
debug:
63
p.setGravity
(0, 0, 0, physicsClientId=self.
physicsClient
)
64
self.
roll_Id
=
p.addUserDebugParameter
(
"roll_cmd"
, -0.01, 0.01, 0)
65
self.
pitch_Id
=
p.addUserDebugParameter
(
"pitch_cmd"
, -0.01, 0.01, 0)
66
self.
yaw_Id
=
p.addUserDebugParameter
(
"yaw_cmd"
, -0.01, 0.01, 0)
67
68
def
apply_force_and_moments
(self,rpm):
69
''' rpm = [ quadrotor prop rpms ]'''
70
forces =
np.array
(rpm**2)*self.
KF
71
torques =
np.array
(rpm**2)*self.KM
72
73
f_noise =
np.random.normal
(0, 0.01, len(rpm))
74
m_noise =
np.random.normal
(0, 0.001,len(rpm))
75
76
# f_noise = np.zeros(4)
77
# m_noise = np.zeros(4)
78
79
forces += f_noise
80
torques += m_noise
81
82
z_torque = (torques[0] - torques[1] + torques[2] - torques[3])
83
for
i
in
range(4):
#FIXME : decide according to commands length
84
p.applyExternalForce
(self.
vehicle
,
85
i,
86
forceObj=[f_noise[0], f_noise[1], forces[i]],
87
posObj=[0, 0, 0],
88
flags=
p.LINK_FRAME
,
89
physicsClientId=self.
physicsClient
90
)
91
p.applyExternalTorque
(self.
vehicle
,
92
-1,
# FIXME : this is not correct , use center of mass !!!
93
torqueObj=[m_noise[0], m_noise[1], z_torque],
94
flags=
p.LINK_FRAME
,
95
physicsClientId=self.
physicsClient
96
)
97
98
def
step
(self,commands):
99
100
if
not
isinstance
(commands,
np.ndarray
):
101
commands =
np.array
(commands)
102
103
# little hack to scale commands. It should probably be in the URDF file.
104
commands *= 30
105
106
# t = time.time()
107
# if (t - self.last_time_print) > 0.5:
108
# self.last_time_print = t
109
# print(f"{commands[0]:.2f} {commands[1]:.2f} {commands[2]:.2f} {commands[3]:.2f}")
110
111
self.
apply_force_and_moments
(commands)
112
p.stepSimulation
(physicsClientId=self.
physicsClient
)
113
return
self.
get_observation
()
114
115
def
step_debug
(self,commands):
116
# commands are not used...
117
roll_cmd =
p.readUserDebugParameter
(self.
roll_Id
)
118
pitch_cmd =
p.readUserDebugParameter
(self.
pitch_Id
)
119
yaw_cmd =
p.readUserDebugParameter
(self.
yaw_Id
)
120
121
# p.applyExternalForce(self.vehicle,
122
# -1,
123
# forceObj=[0, 0, 9 + yaw_cmd*100],
124
# posObj=[0, 0, 0],
125
# flags=p.LINK_FRAME,
126
# physicsClientId=self.physicsClient
127
# )
128
129
p.applyExternalTorque
(self.
vehicle
,
130
-1,
# FIXME : this is not correct , use center of mass !!!
131
torqueObj=[roll_cmd, pitch_cmd, yaw_cmd],
132
flags=
p.LINK_FRAME
,
133
physicsClientId=self.
physicsClient
134
)
135
136
p.stepSimulation
(physicsClientId=self.
physicsClient
)
137
return
self.
get_observation
()
138
139
def
get_observation
(self):
140
# Get observation
141
v_pos, v_quat =
p.getBasePositionAndOrientation
(self.
vehicle
)
142
v_rpy =
p.getEulerFromQuaternion
(v_quat)
143
v_vel, v_ang_v =
p.getBaseVelocity
(self.
vehicle
)
144
145
self.
accel
= (
np.array
(v_vel) - self.
vel
)/self.
dt
146
self.
vel
=
np.array
(v_vel)
147
self.
ang_accel
= (
np.array
(v_ang_v) - self.
ang_vel
)/self.
dt
148
self.
ang_vel
=
np.array
(v_ang_v)
149
R =
np.array
(
p.getMatrixFromQuaternion
(v_quat)).
reshape
(3, 3)
150
body_ang_vel =
R.T.dot
(self.
ang_vel
)
151
body_ang_accel =
R.T.dot
(self.
ang_accel
)
152
153
self.
observation
= {
'pos'
:v_pos,
154
'quat'
:v_quat,
155
'rpy'
:v_rpy,
156
'vel'
:
tuple
(self.
vel
),
157
'ang_v'
:
tuple
(body_ang_vel),
158
'accel'
:
tuple
(self.
accel
),
159
'ang_accel'
:
tuple
(body_ang_accel)
160
}
161
return
self.
observation
162
163
def
reset
(self):
164
# Reset the simulation and the state
165
# p.resetSimulation(physicsClientId=self.physicsClient) # FIXME : this is not the correct way to reset the simulation
166
p.resetBasePositionAndOrientation
(self.
vehicle
, self.
vehicle_start_pos
, self.
vehicle_start_orientation
)
167
p.resetBaseVelocity
(self.
vehicle
, [0, 0, 0], [0, 0, 0])
168
169
return
self.
get_observation
()
170
171
172
173
if
__name__ ==
"__main__"
:
174
from
time
import
sleep
175
debug =
True
176
m =
BulletFDM
(GUI=
True
, debug=debug)
177
178
# An example simulation loop with random commands generation
179
while
1:
180
for
i
in
range(200):
181
# commands = np.array([10., 10., 10., 10.]) # fixed rpms
182
commands =
np.random.normal
(13., 0.5, 4)
# random rpms
183
if
debug:
184
m.step_debug
(commands)
185
else
:
186
m.step
(commands)
187
sleep(0.05)
# FIXME : checck the computation time and sleep to sync realtime...
188
m.reset
()
reset
static uint8_t reset[3]
Definition
baro_MS5534A.c:83
simple_quad_sim.BulletFDM
Definition
simple_quad_sim.py:12
simple_quad_sim.BulletFDM.accel
accel
Definition
simple_quad_sim.py:53
simple_quad_sim.BulletFDM.dt
dt
Definition
simple_quad_sim.py:22
simple_quad_sim.BulletFDM.roll_Id
roll_Id
Definition
simple_quad_sim.py:64
simple_quad_sim.BulletFDM.yaw_Id
yaw_Id
Definition
simple_quad_sim.py:66
simple_quad_sim.BulletFDM.step_debug
step_debug(self, commands)
Definition
simple_quad_sim.py:115
simple_quad_sim.BulletFDM.physicsClient
physicsClient
Definition
simple_quad_sim.py:24
simple_quad_sim.BulletFDM.vel
vel
Definition
simple_quad_sim.py:52
simple_quad_sim.BulletFDM.textureId
textureId
Definition
simple_quad_sim.py:33
simple_quad_sim.BulletFDM.vehicle_start_pos
vehicle_start_pos
Definition
simple_quad_sim.py:35
simple_quad_sim.BulletFDM.apply_force_and_moments
apply_force_and_moments(self, rpm)
Definition
simple_quad_sim.py:68
simple_quad_sim.BulletFDM.ang_accel
ang_accel
Definition
simple_quad_sim.py:56
simple_quad_sim.BulletFDM.KF
KF
Definition
simple_quad_sim.py:50
simple_quad_sim.BulletFDM.planeId
planeId
Definition
simple_quad_sim.py:32
simple_quad_sim.BulletFDM.__init__
__init__(self, dt=0.02, GUI=True, debug=False, urdf="robobee.urdf")
Definition
simple_quad_sim.py:13
simple_quad_sim.BulletFDM.pitch_Id
pitch_Id
Definition
simple_quad_sim.py:65
simple_quad_sim.BulletFDM.ang_vel
ang_vel
Definition
simple_quad_sim.py:55
simple_quad_sim.BulletFDM.vehicle
vehicle
Definition
simple_quad_sim.py:39
simple_quad_sim.BulletFDM.vehicle_start_orientation
vehicle_start_orientation
Definition
simple_quad_sim.py:36
simple_quad_sim.BulletFDM.observation
observation
Definition
simple_quad_sim.py:59
simple_quad_sim.BulletFDM.get_observation
get_observation(self)
Definition
simple_quad_sim.py:139
foo
uint16_t foo
Definition
main_demo5.c:58
step
uint8_t step
Definition
max7456.c:140
sw
simulator
nps
pybullet
simple_quad_sim.py
Generated on Wed Oct 28 2026 08:52:03 for Paparazzi UAS by
1.9.8