20 #include "generated/airframe.h"
21 #include "generated/flight_plan.h"
25 #define _WIDEN(x) L ## x
26 #define WIDEN(x) _WIDEN(x)
29 #define PYTHON_EXEC "python3"
34 #define PYBULLET_GUI TRUE
37 #ifdef NPS_ACTUATORS_ORDER
38 int actuators_order[ACTUATORS_NB] = NPS_ACTUATORS_ORDER;
40 #error "[PyBullet] missing NPS_ACTUATORS_ORDER define!"
43 #ifndef NPS_PYBULLET_MODULE
44 #define NPS_PYBULLET_MODULE "simple_quad_sim"
45 MESSAGE(
"NPS_PYBULLET_MODULE not defined, take 'simple_quad_sim' as default value.")
49 #ifndef NPS_PYBULLET_URDF
50 #define NPS_PYBULLET_URDF "robobee.urdf"
51 MESSAGE(
"NPS_PYBULLET_URDF not defined, take 'robobee.urdf' as default value.")
75 static void py_check(
bool exit_on_error,
int line_nb);
81 static void get_pos(PyObject* ppos);
82 static void get_vel(PyObject* pvel);
83 static void get_acc(PyObject* pacc);
110 double dummy_commands[] = {1, 2, 3, 4};
117 PyObject* pcmd = PyList_New(commands_nb);
119 for(
int i=0; i<commands_nb; i++) {
120 int j = actuators_order[i];
121 PyList_SetItem(pcmd, i, PyFloat_FromDouble(
commands[j]));
128 PyObject* ret = PyObject_CallMethod(
bullet_fdm,
"step",
"(O)", pcmd);
132 PyObject* ppos = PyDict_GetItemString(ret,
"pos");
133 PyObject* pvel = PyDict_GetItemString(ret,
"vel");
134 PyObject* pacc = PyDict_GetItemString(ret,
"accel");
136 PyObject* pquat = PyDict_GetItemString(ret,
"quat");
137 PyObject* pang_v = PyDict_GetItemString(ret,
"ang_v");
138 PyObject* pang_acc = PyDict_GetItemString(ret,
"ang_accel");
157 enu_pos.
x = PyFloat_AsDouble(PyTuple_GetItem(ppos, 0));
158 enu_pos.
y = PyFloat_AsDouble(PyTuple_GetItem(ppos, 1));
159 enu_pos.
z = PyFloat_AsDouble(PyTuple_GetItem(ppos, 2));
173 enu_vel.
x = PyFloat_AsDouble(PyTuple_GetItem(pvel, 0));
174 enu_vel.
y = PyFloat_AsDouble(PyTuple_GetItem(pvel, 1));
175 enu_vel.
z = PyFloat_AsDouble(PyTuple_GetItem(pvel, 2));
192 PyFloat_AsDouble(PyTuple_GetItem(pacc, 0)),
193 PyFloat_AsDouble(PyTuple_GetItem(pacc, 1)),
194 PyFloat_AsDouble(PyTuple_GetItem(pacc, 2)),
225 PyFloat_AsDouble(PyTuple_GetItem(pquat, 3)),
226 PyFloat_AsDouble(PyTuple_GetItem(pquat, 1)),
227 PyFloat_AsDouble(PyTuple_GetItem(pquat, 0)),
228 -PyFloat_AsDouble(PyTuple_GetItem(pquat, 2)),
241 sim_rates.
x = PyFloat_AsDouble(PyTuple_GetItem(pang_vel, 1));
242 sim_rates.
y = PyFloat_AsDouble(PyTuple_GetItem(pang_vel, 0));
243 sim_rates.
z = -PyFloat_AsDouble(PyTuple_GetItem(pang_vel, 2));
258 sim_rotaccel.
x = PyFloat_AsDouble(PyTuple_GetItem(pang_acc, 1));
259 sim_rotaccel.
y = PyFloat_AsDouble(PyTuple_GetItem(pang_acc, 0));
260 sim_rotaccel.
z = -PyFloat_AsDouble(PyTuple_GetItem(pang_acc, 2));
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;
314 double dir __attribute__((unused)))
319 double wind_east __attribute__((unused)),
320 double wind_down __attribute__((unused)))
325 int turbulence_severity __attribute__((unused)))
330 double h __attribute__((unused)))
337 PyConfig_InitPythonConfig(&
config);
340 config.configure_c_stdio = 1;
341 config.buffered_stdio = 0;
349 PyObject *sys_path = PySys_GetObject(
"path");
350 PyObject *module_path = PyUnicode_FromString( PAPARAZZI_SRC
"/sw/simulator/nps/pybullet");
351 PyList_Append(sys_path, module_path);
352 Py_DECREF(module_path);
357 PyObject* bullet_fdm_class = PyObject_GetAttrString(
fdm_module,
"BulletFDM");
360 PyObject* fdm_ctor_args = Py_BuildValue(
"(d)", dt);
362 bullet_fdm = PyObject_Call(bullet_fdm_class, fdm_ctor_args, fdm_ctor_kwargs);
365 Py_DECREF(fdm_ctor_args);
366 Py_DECREF(bullet_fdm_class);
370 if (PyStatus_Exception(*
status)) {
373 Py_ExitStatusException(*
status);
379 static void py_check(
bool exit_on_error,
int line_nb) {
380 if(PyErr_Occurred()) {
381 printf(
"Error at line %d\n", line_nb);
static void h(const real32_T x[7], const real32_T q[4], real32_T y[6])
pprz_t commands[COMMANDS_NB]
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.
#define EULERS_COPY(_a, _b)
#define QUAT_COPY(_qo, _qi)
#define VECT3_COPY(_a, _b)
double alt
in meters above WGS84 reference ellipsoid
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.
PRINT_CONFIG_MSG("USE_INS_NAV_INIT defaulting to TRUE")
struct NedCoor_d ltpprz_ecef_vel
velocity in ltppprz frame, wrt ECEF frame
double pressure_sl
pressure at sea level in Pascal
struct DoubleQuat ltpprz_to_body_quat
double total_pressure
total atmospheric pressure in Pascal
struct EcefCoor_d ecef_pos
struct NedCoor_d ltpprz_pos
struct DoubleRates body_inertial_rotvel
struct NedCoor_d ltp_ecef_vel
velocity in LTP frame, wrt ECEF frame
struct NedCoor_d ltpprz_ecef_accel
accel in ltppprz frame, wrt ECEF frame
double dynamic_pressure
dynamic pressure in Pascal
struct DoubleEulers ltp_to_body_eulers
struct EcefCoor_d ecef_ecef_accel
acceleration in ECEF frame, wrt ECEF frame
double pressure
current (static) atmospheric pressure in Pascal
struct DoubleQuat ltp_to_body_quat
struct DoubleRates body_ecef_rotvel
struct EcefCoor_d ecef_ecef_vel
velocity in ECEF frame, wrt ECEF frame
struct DoubleRates body_inertial_rotaccel
double temperature
current temperature in degrees Celcius
struct DoubleRates body_ecef_rotaccel
struct DoubleEulers ltpprz_to_body_eulers
struct DoubleVect3 body_accel
acceleration in body frame as measured by an accelerometer (incl.
struct NedCoor_d ltp_ecef_accel
acceleration in LTP frame, wrt ECEF frame
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
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...
#define NPS_PYBULLET_URDF
void nps_fdm_set_temperature(double temp, double h)
Set temperature in degrees Celcius at given height h above MSL.
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)
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.
API to get/set the generic vehicle states.
static const struct usb_config_descriptor config