Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
nps_fdm_pybullet.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2021 Fabien-B <fabien-b@github.com>
3 *
4 * This file is part of paparazzi. See LICENCE file.
5 */
6
7#include "nps_fdm.h"
8
9#include <stdlib.h>
10#include <stdio.h>
11#include <Python.h>
12
13#include "math/pprz_geodetic.h"
16#include "math/pprz_algebra.h"
18#include "math/pprz_isa.h"
19
20#include "generated/airframe.h"
21#include "generated/flight_plan.h"
22
23#include "state.h"
24
25#define _WIDEN(x) L ## x
26#define WIDEN(x) _WIDEN(x)
27
28#ifndef PYTHON_EXEC
29#define PYTHON_EXEC "python3"
30#endif
31MESSAGE("PyBullet using" VALUE(PYTHON_EXEC))
32
33#ifndef PYBULLET_GUI
34#define PYBULLET_GUI TRUE
35#endif
36
37#ifdef NPS_ACTUATORS_ORDER
39#else
40 #error "[PyBullet] missing NPS_ACTUATORS_ORDER define!"
41#endif
42
43#ifndef NPS_PYBULLET_MODULE
44#define NPS_PYBULLET_MODULE "simple_quad_sim"
45MESSAGE("NPS_PYBULLET_MODULE not defined, take 'simple_quad_sim' as default value.")
46#endif
47
48
49#ifndef NPS_PYBULLET_URDF
50#define NPS_PYBULLET_URDF "robobee.urdf"
51MESSAGE("NPS_PYBULLET_URDF not defined, take 'robobee.urdf' as default value.")
52#endif
53
54
55// NpsFdm structure
56struct NpsFdm fdm;
57
58// Reference point
59static struct LtpDef_d ltpdef;
60
61//rotation from pybullet to pprz
63 1/sqrt(2),
64 0,
65 0,
66 1/sqrt(2),
67};
68
69// python object declarations
72
73// static python related function declaration
75static void py_check(bool exit_on_error, int line_nb);
76static void python_init(double dt);
77
78// Static functions declaration
79static void init_ltp(void);
80
81static void get_pos(PyObject* ppos);
82static void get_vel(PyObject* pvel);
83static void get_acc(PyObject* pacc);
84
85static void get_orient(PyObject* porient);
86static void get_ang_vel(PyObject* pang_vel);
87static void get_ang_acc(PyObject* pang_acc);
88
89void nps_fdm_init(double dt)
90{
91 python_init(dt);
92
93 fdm.init_dt = dt; // (1 / simulation freq)
94 fdm.curr_dt = dt;
95 fdm.time = dt;
96
98
99 fdm.nan_count = 0;
100 fdm.pressure = -1;
102 fdm.total_pressure = -1;
104 fdm.temperature = -1;
105
107 init_ltp();
108
109 // run a first step to initialize all fdm fields
110 double dummy_commands[] = {1, 2, 3, 4};
112}
113
114void nps_fdm_run_step(bool launch __attribute__((unused)), double *commands, int commands_nb __attribute__((unused)))
115{
116 // TODO create a np.array instead ?
118
119 for(int i=0; i<commands_nb; i++) {
120 int j = actuators_order[i];
122 }
123
124 if(commands[0] < 0) {
125 return;
126 }
127
128 PyObject* ret = PyObject_CallMethod(bullet_fdm, "step", "(O)", pcmd);
129 py_check(true, __LINE__);
130
131 // borrowed references
134 PyObject* pacc = PyDict_GetItemString(ret, "accel");
135
138 PyObject* pang_acc = PyDict_GetItemString(ret, "ang_accel");
139 //PyObject* prpy = PyDict_GetItemString(ret, "rpy");
140 py_check(true, __LINE__);
141
142
143 get_pos(ppos);
145 get_vel(pvel);
146 get_acc(pacc);
149
152}
153
154static void get_pos(PyObject* ppos) {
155 // get position from pybullet, in ENU, in the local frame
156 struct EnuCoor_d enu_pos;
160 py_check(true, __LINE__);
161
162 /*********** positions *************/
166 fdm.hmsl = -fdm.ltpprz_pos.z; //FIXME
167 fdm.agl = fdm.hmsl; //FIXME
168}
169
170static void get_vel(PyObject* pvel) {
171 // get velocity from pybullet, in ENU wrt local frame (fixed/world)
172 struct EnuCoor_d enu_vel;
176 py_check(true, __LINE__);
177
178 /*********** velocities *************/
183 // /** velocity in body frame, wrt ECEF frame */
184 // struct DoubleVect3 body_ecef_vel; /* aka UVW */
185 // /** velocity in ltppprz frame, wrt ECEF frame */
187}
188
189static void get_acc(PyObject* pacc) {
190
191 struct EnuCoor_d enu_accel = {
195 };
196
201
202
204
206 struct DoubleVect3 tmp = {
209 fdm.ltp_ecef_accel.z - 10,
210 };
212
213 // /** acceleration in body frame, wrt ECEF frame */
214 // fdm.body_ecef_accel;
215 // /** acceleration in body frame, wrt ECI inertial frame */
216 // fdm.body_inertial_accel;
217
218
219}
220
236
254
269
270
271
272/**************************
273 ** Generating LTP plane **
274 **************************/
275
276static void init_ltp(void)
277{
278
279 struct LlaCoor_d llh_nav0; /* Height above the ellipsoid */
280 llh_nav0.lat = RadOfDeg((double)NAV_LAT0 / 1e7);
281 llh_nav0.lon = RadOfDeg((double)NAV_LON0 / 1e7);
282 llh_nav0.alt = NAV_ALT0 / 1000.0;
283
284 struct EcefCoor_d ecef_nav0;
285
287
290
291
292// TODO vérifier tout ça
293 fdm.ltp_g.x = 0.;
294 fdm.ltp_g.y = 0.;
295 fdm.ltp_g.z = 0.; // accel data are already with the correct format
296
297#ifdef AHRS_H_X
301 PRINT_CONFIG_MSG("Using magnetic field as defined in airframe file.")
302#else
303 fdm.ltp_h.x = 0.4912;
304 fdm.ltp_h.y = 0.1225;
305 fdm.ltp_h.z = 0.8624;
306#endif
307
308}
309
310
311/*****************************************************/
312// Atmosphere function (we don't need that features) //
313void nps_fdm_set_wind(double speed __attribute__((unused)),
314 double dir __attribute__((unused)))
315{
316}
317
319 double wind_east __attribute__((unused)),
320 double wind_down __attribute__((unused)))
321{
322}
323
324void nps_fdm_set_turbulence(double wind_speed __attribute__((unused)),
325 int turbulence_severity __attribute__((unused)))
326{
327}
328
329void nps_fdm_set_temperature(double temp __attribute__((unused)),
330 double h __attribute__((unused)))
331{
332}
333
334static void python_init(double dt) {
338
339 // needed for the prints
340 config.configure_c_stdio = 1;
341 config.buffered_stdio = 0;
342
347
348 // add path to sys.path
350 PyObject *module_path = PyUnicode_FromString( PAPARAZZI_SRC "/sw/simulator/nps/pybullet");
353
355 py_check(true, __LINE__);
356
358 py_check(true, __LINE__);
359
363
364 py_check(true, __LINE__);
367}
368
371 printf("error\n");
374 exit(1);
375 }
376}
377
378
379static void py_check(bool exit_on_error, int line_nb) {
380 if(PyErr_Occurred()) {
381 printf("Error at line %d\n", line_nb);
382 PyErr_Print();
383 if(exit_on_error) {
384 exit(1);
385 }
386 }
387}
static void h(const real32_T x[7], const real32_T q[4], real32_T y[6])
static uint8_t status
double psi
in radians
double p
in rad/s^2
double q
in rad/s^2
double r
in rad/s^2
void double_eulers_of_quat(struct DoubleEulers *e, struct DoubleQuat *q)
void double_quat_vmult(struct DoubleVect3 *v_out, struct DoubleQuat *q, struct DoubleVect3 *v_in)
void double_quat_comp(struct DoubleQuat *a2c, struct DoubleQuat *a2b, struct DoubleQuat *b2c)
Composition (multiplication) of two quaternions.
Roation quaternion.
#define EULERS_COPY(_a, _b)
#define QUAT_COPY(_qo, _qi)
#define VECT3_COPY(_a, _b)
double y
in meters
double z
in meters
double x
in meters
double lat
in radians
double x
in meters
void ltp_def_from_ecef_d(struct LtpDef_d *def, struct EcefCoor_d *ecef)
void ecef_of_enu_vect_d(struct EcefCoor_d *ecef, struct LtpDef_d *def, struct EnuCoor_d *enu)
void lla_of_ecef_d(struct LlaCoor_d *lla, struct EcefCoor_d *ecef)
void ecef_of_lla_d(struct EcefCoor_d *ecef, struct LlaCoor_d *lla)
void ecef_of_enu_point_d(struct EcefCoor_d *ecef, struct LtpDef_d *def, struct EnuCoor_d *enu)
vector in EarthCenteredEarthFixed coordinates
vector in East North Up coordinates Units: meters
vector in Latitude, Longitude and Altitude
definition of the local (flat earth) coordinate system
#define VECT3_NED_OF_ENU(_o, _i)
#define PPRZ_ISA_SEA_LEVEL_PRESSURE
ISA sea level standard atmospheric pressure in Pascal.
Definition pprz_isa.h:50
PRINT_CONFIG_MSG("USE_INS_NAV_INIT defaulting to TRUE")
uint16_t foo
Definition main_demo5.c:58
double time
Definition nps_fdm.h:46
struct NedCoor_d ltpprz_ecef_vel
velocity in ltppprz frame, wrt ECEF frame
Definition nps_fdm.h:79
struct DoubleVect3 ltp_g
Definition nps_fdm.h:104
double pressure_sl
pressure at sea level in Pascal
Definition nps_fdm.h:114
struct DoubleQuat ltpprz_to_body_quat
Definition nps_fdm.h:93
double init_dt
Definition nps_fdm.h:47
double total_pressure
total atmospheric pressure in Pascal
Definition nps_fdm.h:111
double hmsl
Definition nps_fdm.h:56
struct EcefCoor_d ecef_pos
Definition nps_fdm.h:53
struct NedCoor_d ltpprz_pos
Definition nps_fdm.h:54
struct DoubleRates body_inertial_rotvel
Definition nps_fdm.h:101
struct NedCoor_d ltp_ecef_vel
velocity in LTP frame, wrt ECEF frame
Definition nps_fdm.h:74
struct NedCoor_d ltpprz_ecef_accel
accel in ltppprz frame, wrt ECEF frame
Definition nps_fdm.h:81
double agl
Definition nps_fdm.h:61
struct DoubleVect3 ltp_h
Definition nps_fdm.h:105
double dynamic_pressure
dynamic pressure in Pascal
Definition nps_fdm.h:112
struct DoubleEulers ltp_to_body_eulers
Definition nps_fdm.h:92
struct EcefCoor_d ecef_ecef_accel
acceleration in ECEF frame, wrt ECEF frame
Definition nps_fdm.h:66
double pressure
current (static) atmospheric pressure in Pascal
Definition nps_fdm.h:110
double curr_dt
Definition nps_fdm.h:48
struct DoubleQuat ltp_to_body_quat
Definition nps_fdm.h:91
struct DoubleRates body_ecef_rotvel
Definition nps_fdm.h:97
struct EcefCoor_d ecef_ecef_vel
velocity in ECEF frame, wrt ECEF frame
Definition nps_fdm.h:64
struct DoubleRates body_inertial_rotaccel
Definition nps_fdm.h:102
double temperature
current temperature in degrees Celcius
Definition nps_fdm.h:113
struct DoubleRates body_ecef_rotaccel
Definition nps_fdm.h:98
struct DoubleEulers ltpprz_to_body_eulers
Definition nps_fdm.h:94
struct LlaCoor_d lla_pos
Definition nps_fdm.h:55
struct DoubleVect3 body_accel
acceleration in body frame as measured by an accelerometer (incl.
Definition nps_fdm.h:87
bool on_ground
Definition nps_fdm.h:49
int nan_count
Definition nps_fdm.h:50
struct NedCoor_d ltp_ecef_accel
acceleration in LTP frame, wrt ECEF frame
Definition nps_fdm.h:76
void nps_fdm_set_wind_ned(double wind_north, double wind_east, double wind_down)
static void python_init(double dt)
void nps_fdm_init(double dt)
NPS FDM rover init.
static void init_ltp(void)
struct DoubleQuat quat_to_pprz
#define PYTHON_EXEC
void nps_fdm_run_step(bool launch, double *commands, int commands_nb)
Minimum complexity flight dynamic model In legacy Paparazzi simulator, was implemented in OCaml and c...
PyObject * bullet_fdm
PyObject * fdm_module
#define NPS_PYBULLET_URDF
void nps_fdm_set_temperature(double temp, double h)
Set temperature in degrees Celcius at given height h above MSL.
#define WIDEN(x)
static void get_vel(PyObject *pvel)
static void get_ang_acc(PyObject *pang_acc)
static void get_orient(PyObject *porient)
static void get_ang_vel(PyObject *pang_vel)
void nps_fdm_set_turbulence(double wind_speed, int turbulence_severity)
#define PYBULLET_GUI
static void py_check_status(PyConfig *config, PyStatus *status)
#define NPS_PYBULLET_MODULE
static void get_pos(PyObject *ppos)
void nps_fdm_set_wind(double speed, double dir)
static void get_acc(PyObject *pacc)
struct NpsFdm fdm
Holds all necessary NPS FDM state information.
static void py_check(bool exit_on_error, int line_nb)
static struct LtpDef_d ltpdef
Paparazzi generic algebra macros.
Paparazzi floating point algebra.
Paparazzi generic macros for geodetic calculations.
Paparazzi double-precision floating point math for geodetic calculations.
Paparazzi floating point math for geodetic calculations.
Paparazzi atmospheric pressure conversion utilities.
static const ShellCommand commands[]
Definition shell_arch.c:78
static const float dir[]
API to get/set the generic vehicle states.
#define TRUE
Definition std.h:4
static const struct usb_config_descriptor config
Definition usb_ser_hw.c:200